typedef struct _tdm_private_client_voutput {
tdm_private_client_output base;
struct wl_tdm_voutput *wl_voutput;
+
+ struct
+ {
+ int count;
+ tdm_client_output_mode *modes;
+ } available_modes;
+
uint32_t msg;
} tdm_private_client_voutput;
private_voutput->base.private_client = private_client;
- snprintf(private_voutput->base.name, TDM_NAME_LEN, "%s", name);
private_voutput->wl_voutput = wl_tdm_create_voutput((struct wl_tdm *)wrapper, private_voutput->base.name);
wl_proxy_wrapper_destroy(wrapper);
if (!private_voutput->wl_voutput) {
if (!private_voutput)
return;
+ wl_tdm_voutput_destroy(private_voutput->wl_voutput);
+
free(private_voutput);
}
tdm_error
tdm_client_voutput_set_available_modes(tdm_client_voutput *voutput, const tdm_client_output_mode *modes, int count)
{
+ tdm_private_client_voutput *private_voutput;
+
TDM_RETURN_VAL_IF_FAIL(voutput != NULL, TDM_ERROR_INVALID_PARAMETER);
- TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
- TDM_RETURN_VAL_IF_FAIL(count > 0, TDM_ERROR_INVALID_PARAMETER);
+
+ if ((count > 0) && (modes == NULL))
+ return TDM_ERROR_INVALID_PARAMETER;
+
+ private_voutput = (tdm_private_client_voutput *)voutput;
+
+ if (private_voutput->base.connection == TDM_OUTPUT_CONN_STATUS_CONNECTED)
+ return TDM_ERROR_BAD_REQUEST;
+
+ if (private_voutput->available_modes.modes)
+ free(private_voutput->available_modes.modes);
+
+ private_voutput->available_modes.count = count;
+
+ if (count != 0)
+ {
+ private_voutput->available_modes.modes = calloc(count, sizeof(tdm_client_output_mode));
+ memcpy(private_voutput->available_modes.modes, modes, sizeof(tdm_client_output_mode) * count);
+ }
return TDM_ERROR_NONE;
}
tdm_error
tdm_client_output_connect(tdm_client_output *output)
{
+ tdm_private_client_output *private_output;
+ tdm_private_client_voutput *private_voutput;
+ tdm_client_output_mode *modes;
+ int i;
+
TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+ private_output = (tdm_private_client_output *)output;
+ private_voutput = (tdm_private_client_voutput *)output;
+
+ TDM_RETURN_VAL_IF_FAIL(private_output->connection != TDM_OUTPUT_CONN_STATUS_CONNECTED,
+ TDM_ERROR_BAD_REQUEST);
+
+ private_output->connection = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+
+ modes = private_voutput->available_modes.modes;
+ for (i = 0; i < private_voutput->available_modes.count; i++)
+ {
+ wl_tdm_voutput_set_available_modes(private_voutput->wl_voutput, i,
+ modes[i].clock, modes[i].hdisplay,
+ modes[i].hsync_start, modes[i].hsync_end,
+ modes[i].htotal, modes[i].hskew,
+ modes[i].vdisplay, modes[i].vsync_start,
+ modes[i].vsync_end, modes[i].vtotal,
+ modes[i].vscan, modes[i].vrefresh,
+ modes[i].flags, modes[i].type,
+ modes[i].name);
+ }
+
+ wl_tdm_voutput_connect(private_voutput->wl_voutput);
+
return TDM_ERROR_NONE;
}
tdm_error
tdm_client_output_disconnect(tdm_client_output *output)
{
+ tdm_private_client_voutput *private_voutput;
+ tdm_private_client_output *private_output;
+
TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+ private_output = (tdm_private_client_output *)output;
+ private_voutput = (tdm_private_client_voutput *)output;
+
+ TDM_RETURN_VAL_IF_FAIL(private_output->connection != TDM_OUTPUT_CONN_STATUS_DISCONNECTED,
+ TDM_ERROR_BAD_REQUEST);
+
+ private_output->connection = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+ wl_tdm_voutput_disconnect(private_voutput->wl_voutput);
+
return TDM_ERROR_NONE;
}
void *user_data);
/* Virtual Output */
+/* this is a copy of server side's tdm_output_mode */
typedef struct _tdm_client_output_mode {
- char name[TDM_NAME_LEN]; /**< The output name */
- unsigned int mode_count; /**< The count of available modes */
- unsigned int prop_count; /**< The count of available properties */
- unsigned int mmWidth; /**< The physical width (milimeter) */
- unsigned int mmHeight; /**< The physical height (milimeter) */
- unsigned int subpixel; /**< The subpixel */
+ unsigned int clock;
+ unsigned int hdisplay, hsync_start, hsync_end, htotal, hskew;
+ unsigned int vdisplay, vsync_start, vsync_end, vtotal, vscan;
+ unsigned int vrefresh;
+ unsigned int flags;
+ unsigned int type;
+ char name[TDM_NAME_LEN];
} tdm_client_output_mode;
typedef void tdm_client_voutput;
protected:
static tdm_client *client;
static tdm_client_voutput *voutput;
- const int MODE_COUNT = 1;
+ const int MODE_COUNT = 2;
private:
static pid_t server_pid;
for (i = 0; i < count; i++)
{
- modes[i].mmHeight = 1234;
- modes[i].mmWidth = 1234;
- modes[i].mode_count = 0;
- modes[i].prop_count = 0;
- modes[i].subpixel = 0;
- snprintf(modes[i].name, TDM_NAME_LEN, "TestModeSetting");
+ modes[i].clock = 1;
+ modes[i].hdisplay = 2;
+ modes[i].hsync_start = 3;
+ modes[i].hsync_end = 4;
+ modes[i].htotal = 5;
+ modes[i].hskew = 6;
+ modes[i].vdisplay = 7;
+ modes[i].vsync_start = 8;
+ modes[i].vsync_end = 9;
+ modes[i].vtotal = 10;
+ modes[i].vscan = 11;
+ modes[i].vrefresh = 12;
+ modes[i].flags = 13;
+ modes[i].type = 14;
+ snprintf(modes[i].name, TDM_NAME_LEN, "TestModeSetting %d", i);
}
ret = tdm_client_voutput_set_available_modes(this->voutput, modes, count);
ret = tdm_client_voutput_set_available_modes(this->voutput, NULL, count);
ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
-
- ret = tdm_client_voutput_set_available_modes(this->voutput, modes, 0);
- ASSERT_EQ(ret, TDM_ERROR_INVALID_PARAMETER);
}
TEST_F(TDMVirtualOutput, SetPhysicalSize)
ASSERT_NE(output, NULL);
}
+TEST_F(TDMVirtualOutput, Connect)
+{
+ tdm_error ret;
+ tdm_client_output *output;
+
+ output = tdm_client_voutput_get_client_output(this->voutput, &ret);
+ ASSERT_EQ(ret, TDM_ERROR_NONE);
+ ASSERT_NE(output, NULL);
+
+ ret = tdm_client_output_connect(output);
+ ASSERT_EQ(ret, TDM_ERROR_NONE);
+
+ tdm_client_handle_events_timeout(this->client, 0);
+}
+
+TEST_F(TDMVirtualOutput, Disconnect)
+{
+ tdm_error ret;
+ tdm_client_output *output;
+
+ output = tdm_client_voutput_get_client_output(this->voutput, &ret);
+ ASSERT_EQ(ret, TDM_ERROR_NONE);
+ ASSERT_NE(output, NULL);
+
+ ret = tdm_client_output_disconnect(output);
+ ASSERT_EQ(ret, TDM_ERROR_NONE);
+
+ tdm_client_handle_events_timeout(this->client, 0);
+}
+
#if 0
TEST_F(TDMVirtualOutput, FailTestGetClientOutput)
{
<request name="destroy" type="destructor"/>
+ <request name="set_available_modes">
+ <arg name="index" type="uint" summary=""/>
+ <arg name="clock" type="uint" summary=""/>
+ <arg name="hdisplay" type="uint" summary=""/>
+ <arg name="hsync_start" type="uint" summary=""/>
+ <arg name="hsync_end" type="uint" summary=""/>
+ <arg name="htotal" type="uint" summary=""/>
+ <arg name="hskew" type="uint" summary=""/>
+ <arg name="vdisplay" type="uint" summary=""/>
+ <arg name="vsync_start" type="uint" summary=""/>
+ <arg name="vsync_end" type="uint" summary=""/>
+ <arg name="vtotal" type="uint" summary=""/>
+ <arg name="vscan" type="uint" summary=""/>
+ <arg name="vrefresh" type="uint" summary=""/>
+ <arg name="flags" type="uint" summary=""/>
+ <arg name="type" type="uint" summary=""/>
+ <arg name="name" type="string" summary=""/>
+ </request>
+
+ <request name="connect"/>
+
+ <request name="disconnect"/>
+
<event name="ack_message">
<arg name="msg" type="uint" enum="message" summary=""/>
</event>
}
}
+typedef struct _tdm_server_voutput_info {
+ tdm_private_server *private_server;
+ tdm_output_conn_status status;
+ struct
+ {
+ int count;
+ tdm_output_mode *modes;
+ } available_modes;
+} tdm_server_voutput_info;
+
+static void _tdm_voutput_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+_tdm_voutput_cb_set_available_modes(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t index,
+ uint32_t clock,
+ uint32_t hdisplay,
+ uint32_t hsync_start,
+ uint32_t hsync_end,
+ uint32_t htotal,
+ uint32_t hskew,
+ uint32_t vdisplay,
+ uint32_t vsync_start,
+ uint32_t vsync_end,
+ uint32_t vtotal,
+ uint32_t vscan,
+ uint32_t vrefresh,
+ uint32_t flags,
+ uint32_t type,
+ const char *name)
+{
+ tdm_server_voutput_info *voutput_info;
+ tdm_output_mode *tmp_modes, *old_modes;
+ tdm_output_mode *new_mode;
+ int count, len;
+
+ voutput_info = wl_resource_get_user_data(resource);
+
+ count = voutput_info->available_modes.count;
+ old_modes = voutput_info->available_modes.modes;
+ if (index >= count)
+ {
+ if (count > 0)
+ {
+ tmp_modes = malloc(count * sizeof(*tmp_modes));
+ memcpy(tmp_modes, old_modes, count * sizeof(tdm_output_mode));
+ }
+
+ voutput_info->available_modes.count = index + 1;
+ voutput_info->available_modes.modes =
+ realloc(voutput_info->available_modes.modes,
+ sizeof(tdm_output_mode) * (index + 1));
+
+ if (count > 0)
+ {
+ memcpy(voutput_info->available_modes.modes, tmp_modes, count * sizeof(tdm_output_mode));
+ free(tmp_modes);
+ }
+ }
+
+ new_mode = &voutput_info->available_modes.modes[index];
+ new_mode->clock = clock;
+ new_mode->hdisplay = hdisplay;
+ new_mode->hsync_start = hsync_start;
+ new_mode->hsync_end = hsync_end;
+ new_mode->htotal = htotal;
+ new_mode->hskew= hskew;
+ new_mode->vdisplay= vdisplay;
+ new_mode->vsync_start= vsync_start;
+ new_mode->vsync_end = vsync_end;
+ new_mode->vtotal = vtotal;
+ new_mode->vscan = vscan;
+ new_mode->vrefresh = vrefresh;
+ new_mode->flags = flags;
+ new_mode->type = type;
+
+ len = strlen(name);
+ strncpy(new_mode->name, name, len);
+ new_mode->name[len] = '\0';
+}
+
+static void
+_tdm_voutput_cb_connect(struct wl_client *client, struct wl_resource *resource)
+{
+ tdm_server_voutput_info *voutput_info;
+
+ voutput_info = wl_resource_get_user_data(resource);
+ voutput_info->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
+}
+
+static void
+_tdm_voutput_cb_disconnect(struct wl_client *client, struct wl_resource *resource)
+{
+ tdm_server_voutput_info *voutput_info;
+
+ voutput_info = wl_resource_get_user_data(resource);
+ voutput_info->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+
+ /* Do free resources when it's being disconnected */
+ free(voutput_info->available_modes.modes);
+ voutput_info->available_modes.modes = NULL;
+ voutput_info->available_modes.count = 0;
+}
+
+static const struct wl_tdm_voutput_interface tdm_voutput_implementation = {
+ _tdm_voutput_cb_destroy,
+ _tdm_voutput_cb_set_available_modes,
+ _tdm_voutput_cb_connect,
+ _tdm_voutput_cb_disconnect
+};
+
+void
+tdm_voutput_cb_resource_destroy(struct wl_resource *resource)
+{
+ tdm_server_voutput_info *voutput_info;
+
+ voutput_info = wl_resource_get_user_data(resource);
+
+ /* Do free your own resource */
+ free(voutput_info);
+}
+
static void
_tdm_server_cb_create_virtual_output(struct wl_client *client, struct wl_resource *resource, const char *name, uint32_t id)
{
voutput_info->resource = voutput_resource;
voutput_info->output = output;
LIST_INITHEAD(&voutput_info->output_list);
-#if 0
- wl_resource_set_implementation(voutput_resource, &tdm_voutput_implementation,
- voutput_info, destroy_voutput_callback);
-#endif
+
+ wl_resource_set_implementation(voutput_resource,
+ &tdm_voutput_implementation,
+ voutput_info,
+ tdm_voutput_cb_resource_destroy);
+
wl_tdm_voutput_send_ack_message(voutput_resource, WL_TDM_VOUTPUT_MESSAGE_ADDED);
}