meson-display: Add interlace displaymode support. [1/2]

PD#SWPL-24075

Problem:
the interlace display mode not support

Solution:
add interlace display mode support

Verify:
local u212.

Change-Id: I79c232d359f845db464cb19748e8ec49579da88c
Signed-off-by: lingjie li <lingjie.li@amlogic.com>
diff --git a/display_framework/src/extension/weston-6.0/client/drm-help-client.h b/display_framework/src/extension/weston-6.0/client/drm-help-client.h
index a26facc..d537ccb 100644
--- a/display_framework/src/extension/weston-6.0/client/drm-help-client.h
+++ b/display_framework/src/extension/weston-6.0/client/drm-help-client.h
@@ -85,7 +85,9 @@
     /* set system logic ui rect, current not work well */
     void drm_help_client_set_ui_rect(drm_client_ctx* client, drm_output_rect* rect, int connection_id);
 
-    /* set connector display mode */
+    /* set connector display mode
+     * support mode string like: "%dx%m[^@]@%d %u:%u": "1920x1080i@60 16:9"
+     */
     void drm_help_client_switch_mode_s(drm_client_ctx* client, const char* mode_s, int connection_id);
 
     /* set connector's drm properties*/
diff --git a/display_framework/src/extension/weston-6.0/client/main.c b/display_framework/src/extension/weston-6.0/client/main.c
index 63e0f67..6a09831 100644
--- a/display_framework/src/extension/weston-6.0/client/main.c
+++ b/display_framework/src/extension/weston-6.0/client/main.c
@@ -34,7 +34,9 @@
             "Get or change the mode setting of the weston drm output.\n"
             "Options:\n"
             "       -l,--list-modes        \tlist connector support modes\n"
-            "       -c,--change-mode MODE  \tchange connector current mode, MODE format like:%%dx%%d@%%d width,height,refresh\n"
+            "       -c,--change-mode MODE  \tchange current display mode\n"
+            "                              \tMODE format like:\"%%dx%%d[i|d]@%%d %%d:%%d\" width,height,refresh [aspect_ratio_x:aspect_ratio_y],\n"
+            "                              \teg: \"1920x1080i@60 16:9\"\n"
             "       -g,--get-connector-property \"PROPERTY\"\tget connector property\n"
             "       -s,--set-connector-property \"[Content Protection | Color Depth | Color Space]\"=value\tset connector property\n"
             "       -G \"[ui-rect|display-mode]\"\tget [logic ui rect|display mode]\n"
diff --git a/display_framework/src/extension/weston-6.0/compositor-drm-help.c b/display_framework/src/extension/weston-6.0/compositor-drm-help.c
index eaffadd..b76ab73 100644
--- a/display_framework/src/extension/weston-6.0/compositor-drm-help.c
+++ b/display_framework/src/extension/weston-6.0/compositor-drm-help.c
@@ -27,6 +27,17 @@
 #define for_each_list(pos, list_p)  for (pos = list_p; pos->next != NULL; pos = pos->next)
 
 /**
+ *
+ */
+static const char *const aspect_ratio_as_string[] = {
+    "",
+    " 4:3",
+    " 16:9",
+    " 64:27",
+    " 256:135",
+};
+
+/**
  * DRM properties are allocated dynamically, and maintained as DRM objects
  * within the normal object ID space; they thus do not have a stable ID
  * to refer to.
@@ -222,6 +233,72 @@
     return false;
 }
 
+
+bool parse_modestring(const char* modestring, drm_helper_mode* mode) {
+    int32_t width = 0;
+    int32_t height = 0;
+    char* height_str = NULL;
+    uint32_t refresh = 0;
+    uint32_t flags = 0;
+    uint32_t aspect_width = 0;
+    uint32_t aspect_height = 0;
+    char* others = NULL;
+    const char* aspect_ratio = aspect_ratio_as_string[0];
+    int n, k;
+
+    n = sscanf(modestring , "%dx%m[^@]@%d %u:%u", &width, &height_str, &refresh, &aspect_width, &aspect_height);
+    if (n == 5) {
+        if (aspect_width == 4 && aspect_height == 3)
+            aspect_ratio = aspect_ratio_as_string[1];
+        else if (aspect_width == 16 && aspect_height == 9)
+            aspect_ratio = aspect_ratio_as_string[2];
+        else if (aspect_width == 64 && aspect_height == 27)
+            aspect_ratio = aspect_ratio_as_string[3];
+        else if (aspect_width == 256 && aspect_height == 135)
+            aspect_ratio = aspect_ratio_as_string[4];
+        else
+            fprintf(stderr, "Invalid modestring \"%s\"\n", modestring);
+    }
+    if (height_str == NULL || (n != 2 && n != 3 && n != 5)) {
+        if (height_str != NULL) {
+            free(height_str);
+        }
+        return false;
+    }
+    n = sscanf(height_str, "%d%ms", &height, &others);
+    if (n == 0) {
+        free(height_str);
+        return false;
+    }
+    if (n == 2) {
+        n = strlen(others);
+        for (k = 0; k < n; k++) {
+            switch (others[k]) {
+                case 'i':
+                    flags |= DRM_MODE_FLAG_INTERLACE;
+                    break;
+                case 'd':
+                    flags |= DRM_MODE_FLAG_DBLSCAN;
+                    break;
+                default:
+                    break;
+            }
+        }
+        free(others);
+    }
+    mode->width = width;
+    mode->height = height;
+    mode->flags = flags;
+    mode->refresh = refresh;
+    mode->aspect_ratio = aspect_ratio;
+    DEBUG_INFO("set mode to: %dx%d%c %dhz %s", mode->width, mode->height,
+            (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 'i': (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 'd' : ' ',
+            mode->refresh, mode->aspect_ratio);
+    free(height_str);
+    return true;
+}
+
+
 /*
    json formate:
    {
@@ -246,14 +323,14 @@
     json_object_object_get_ex(data_in, "value", &opt);
     DEBUG_INFO("Handle CMD:%s", cmd);
     if (0 == strcmp("set mode", cmd)) {
+        //Support mode string like: "%dx%m[^@]@%d %u:%u": "1920x1080i@60 16:9"
         if (opt == NULL) {
             ret = -1;
         } else {
             const char* value = json_object_get_string(opt);
             DEBUG_INFO("CMD set mode :%s", value);
             drm_helper_mode m;
-            if (3 != sscanf(value, "%dx%d@%d", &m.width, &m.height, &m.refresh/*, &aspect_width, &aspect_height*/)) {
-                DEBUG_INFO("The Value format error");
+            if (false == parse_modestring(value, &m)) {
                 ret = -1;
             } else {
                 pthread_mutex_lock(&mutex);
diff --git a/display_framework/src/extension/weston-6.0/compositor-drm-help.h b/display_framework/src/extension/weston-6.0/compositor-drm-help.h
index 4b91a74..0d70665 100644
--- a/display_framework/src/extension/weston-6.0/compositor-drm-help.h
+++ b/display_framework/src/extension/weston-6.0/compositor-drm-help.h
@@ -25,6 +25,8 @@
 typedef struct _drm_helper_mode {
      int32_t width, height;
      uint32_t refresh;
+     uint32_t flags; /* Use for support drm mode flags, eg: DRM_MODE_FLAG_INTERLACE,DRM_MODE_FLAG_DBLSCAN */
+     const char* aspect_ratio;
 } drm_helper_mode;
 
 typedef struct _drm_helper_rect {
diff --git a/display_framework/src/ipc/ipc.c b/display_framework/src/ipc/ipc.c
index 9772ff4..07a798e 100644
--- a/display_framework/src/ipc/ipc.c
+++ b/display_framework/src/ipc/ipc.c
@@ -239,7 +239,7 @@
         count = ctx->max_fd + 1;
         set = ctx->socket_set;
         ret = select(count, &set, NULL, NULL, NULL);
-        if (ret == -1 || ret == 0) {
+        if (ret <= 0) {
             DEBUG_INFO("listening get error:%s", strerror(errno));
             continue;
         }
@@ -260,6 +260,7 @@
                     //DEBUG_INFO("Get Event from:%d", i);
                     data_in = NULL;
                     ret = read_request(i, &data_in);
+                    int fd_closed = 0;
                     if (ret <= 0) {
                         //DEBUG_INFO("remove client:%d", i);
                         //the client maybe close when the read_request get 0
@@ -267,6 +268,7 @@
                         int tmp;
                         FD_CLR(i, &ctx->socket_set);
                         close(i);
+                        fd_closed = 1;
                         for (tmp = 0; tmp < ctx->connector_count; tmp++) {
                             if (ctx->sfd[tmp] == i) {
                                 ctx->connector_count--;
@@ -287,8 +289,13 @@
                         DEBUG_INFO("Receive msg:%s", json_object_to_json_string(data_in));
                         ctx->msg_handle(data_in, &data_out);
                         if (data_out != NULL) {
-                            DEBUG_INFO("Replay msg:%s", json_object_to_json_string(data_out));
-                            send_request(i, data_out);
+                            if (fd_closed) {
+                                DEBUG_INFO("No receiver msg:%s", json_object_to_json_string(data_out));
+                                json_object_put(data_out);
+                            } else {
+                                DEBUG_INFO("Replay msg:%s", json_object_to_json_string(data_out));
+                                send_request(i, data_out);
+                            }
                         }
                     } else {
                         json_object_put(data_in);