+
+/* LCOV_EXCL_START */
+INTERN tdm_error
+tdm_vblank_set_add_front(tdm_vblank *vblank, unsigned int add_front)
+{
+ tdm_private_vblank *private_vblank = vblank;
+
+ TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
+
+ TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED);
+
+ if (private_vblank->add_front == add_front)
+ return TDM_ERROR_NONE;
+
+ private_vblank->add_front = add_front;
+
+ return TDM_ERROR_NONE;
+}
+/* LCOV_EXCL_STOP */
+
+INTERN tdm_error
+tdm_vblank_set_resource(tdm_vblank *vblank, struct wl_resource *resource)
+{
+ tdm_private_vblank *private_vblank = vblank;
+
+ TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
+ TDM_RETURN_VAL_IF_FAIL(private_vblank->resource == NULL, TDM_ERROR_OPERATION_FAILED);
+
+ private_vblank->resource = resource;
+
+ return TDM_ERROR_NONE;
+}
+
+INTERN double
+tdm_vblank_get_stamp(tdm_vblank *vblank)
+{
+ tdm_private_vblank *private_vblank = vblank;
+
+ TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(vblank), TDM_ERROR_INVALID_PARAMETER);
+
+ return private_vblank->stamp;
+}
+
+static unsigned int
+_tdm_vblank_get_waiting_count(tdm_private_vblank *private_vblank)
+{
+ tdm_vblank_wait_info *wait_info = NULL;
+ unsigned int count = 0;
+
+ LIST_FOR_EACH_ENTRY(wait_info, &private_vblank->HW_wait_list, link) {
+ count++;
+ }
+
+ LIST_FOR_EACH_ENTRY(wait_info, &private_vblank->SW_wait_list, link) {
+ count++;
+ }
+
+ return count;
+}
+
+static void
+_tdm_vblank_get_client_information(tdm_private_vblank *private_vblank, pid_t *pid, const char **name)
+{
+ struct wl_client *client;
+
+ if (!private_vblank->resource)
+ goto no_client;
+
+ client = wl_resource_get_client(private_vblank->resource);
+ if (!client)
+ goto no_client;
+
+ wl_client_get_credentials(client, pid, NULL, NULL);
+ *name = tdm_server_get_client_name(*pid);
+
+ return;
+
+no_client:
+ *pid = 0;
+ *name = NULL;
+ return;
+}
+
+/* LCOV_EXCL_START */
+INTERN void
+tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len)
+{
+ tdm_private_vblank *v = NULL;
+ tdm_output_dpms dpms = TDM_OUTPUT_DPMS_OFF;
+ tdm_output *output = tdm_display_get_output(dpy, 0, NULL);
+
+ if (output)
+ tdm_output_get_dpms(output, &dpms);
+
+ TDM_SNPRINTF(reply, len, "[Client Vblank List]\n");
+ TDM_SNPRINTF(reply, len, "* DPMS: %s\n", tdm_dpms_str(dpms));
+ TDM_SNPRINTF(reply, len, "* global fps: %u\n", vblank_global_fps);
+ TDM_SNPRINTF(reply, len, "----------------------------------------------------------------------------------\n");
+ TDM_SNPRINTF(reply, len, "Name Type Wait Interval Sequence Fps Ignore Offset Fake Process\n");
+ TDM_SNPRINTF(reply, len, "----------------------------------------------------------------------------------\n");
+
+ pthread_mutex_lock(&valid_list_lock);
+ LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) {
+ const char *proc_name = NULL;
+ pid_t pid = 0;
+ unsigned int count;
+
+ _tdm_vblank_get_client_information(v, &pid, &proc_name);
+
+ count = _tdm_vblank_get_waiting_count(v);
+
+ TDM_SNPRINTF(reply, len, "%-8s(%p) ", v->name, v);
+ TDM_SNPRINTF(reply, len, "%-4s ", (v->last_type == VBLANK_EVENT_TYPE_HW) ? "HW" : "SW");
+ TDM_SNPRINTF(reply, len, "%-4s ", (count > 0) ? "O" : " ");
+ TDM_SNPRINTF(reply, len, "%-8d ", v->last_interval);
+ TDM_SNPRINTF(reply, len, "%-8u ", v->last_seq);
+ TDM_SNPRINTF(reply, len, "%-3u ", v->fps);
+ TDM_SNPRINTF(reply, len, "%-6u ", v->ignore_global_fps);
+ TDM_SNPRINTF(reply, len, "%-6d ", v->offset);
+ TDM_SNPRINTF(reply, len, "%-4u ", v->enable_fake);
+ TDM_SNPRINTF(reply, len, "%s(pid:%d)\n", (proc_name) ? proc_name : "Unknown", pid);
+ }
+ pthread_mutex_unlock(&valid_list_lock);
+
+ TDM_SNPRINTF(reply, len, "\n");
+}
+/* LCOV_EXCL_STOP */
+