virtual: erase unused code
[platform/core/uifw/libtdm.git] / backends / virtual / tdm_virtual_display.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "tdm_virtual.h"
6
7 typedef struct _tdm_virtual_output_data tdm_virtual_output_data;
8 typedef struct _tdm_virtual_layer_data tdm_virtual_layer_data;
9 typedef struct _tdm_virtual_event_data tdm_virtual_event_data;
10
11 typedef enum {
12         TDM_VIRTUAL_EVENT_TYPE_WAIT,
13         TDM_VIRTUAL_EVENT_TYPE_COMMIT,
14 } tdm_virtual_event_type;
15
16 struct _tdm_virtual_event_data {
17         struct list_head link;
18
19         tdm_virtual_event_type type;
20         tdm_virtual_output_data *output_data;
21         void *user_data;
22 };
23
24 struct _tdm_virtual_output_data {
25         struct list_head link;
26
27         /* data which are fixed at initializing */
28         tdm_virtual_data *virtual_data;
29
30         uint32_t pipe;
31         tdm_output_mode *output_modes;
32         int mode_count;
33         tdm_output_type connector_type;
34         struct list_head layer_list;
35         tdm_virtual_layer_data *primary_layer;
36
37         /* not fixed data below */
38         tdm_output_vblank_handler vblank_func;
39         tdm_output_commit_handler commit_func;
40
41         tdm_output_conn_status status;
42         tdm_output_status_handler status_func;
43         void *status_user_data;
44
45         int mode_changed;
46         const tdm_output_mode *current_mode;
47
48         tdm_event_loop_source *timer;
49         unsigned int timer_waiting;
50         struct list_head timer_event_list;
51
52         unsigned int mmwidth;
53         unsigned int mmheight;
54
55         char name[TDM_NAME_LEN];        /**< The output name */
56 };
57
58 struct _tdm_virtual_layer_data {
59         struct list_head link;
60
61         /* data which are fixed at initializing */
62         tdm_virtual_data *virtual_data;
63         tdm_virtual_output_data *output_data;
64         tdm_layer_capability capabilities;
65         int zpos;
66
67         /* not fixed data below */
68         tdm_info_layer info;
69         int info_changed;
70
71         tbm_surface_h display_buffer;
72         int display_buffer_changed;
73 };
74
75 static void
76 _tdm_virtual_display_cb_event(tdm_virtual_output_data *output_data, tdm_virtual_event_data *event_data,
77                                                         unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec)
78 {
79         switch (event_data->type) {
80         case TDM_VIRTUAL_EVENT_TYPE_WAIT:
81                 if (output_data->vblank_func)
82                         output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
83                 break;
84         case TDM_VIRTUAL_EVENT_TYPE_COMMIT:
85                 if (output_data->commit_func)
86                         output_data->commit_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
87                 break;
88         default:
89                 break;
90         }
91 }
92
93 static tdm_error
94 _tdm_virtual_display_cb_timeout(void *user_data)
95 {
96         tdm_virtual_output_data *output_data = user_data;
97         tdm_virtual_event_data *e = NULL, *ee = NULL;
98         unsigned int tv_sec, tv_usec;
99         static unsigned int sequence = 0;
100         struct timespec tp;
101
102         sequence++;
103
104         if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
105                 tv_sec = tp.tv_sec;
106                 tv_usec = tp.tv_nsec / 1000;
107         } else {
108                 tv_sec = tv_usec = 0;
109         }
110
111         LIST_FOR_EACH_ENTRY_SAFE(e, ee, &output_data->timer_event_list, link) {
112                 LIST_DEL(&e->link);
113                 _tdm_virtual_display_cb_event(output_data, e, sequence, tv_sec, tv_usec);
114                 free(e);
115         }
116
117         return TDM_ERROR_NONE;
118 }
119
120 static tdm_error
121 _tdm_virtual_display_wait_vblank(tdm_virtual_output_data *output_data, int interval, tdm_virtual_event_data *event_data)
122 {
123         tdm_error ret;
124         unsigned int ms;
125
126         RETURN_VAL_IF_FAIL(output_data->timer != NULL, TDM_ERROR_OPERATION_FAILED);
127         RETURN_VAL_IF_FAIL(output_data->current_mode->vrefresh > 0, TDM_ERROR_OPERATION_FAILED);
128
129         if (output_data->timer_waiting) {
130                 LIST_ADDTAIL(&event_data->link, &output_data->timer_event_list);
131                 return TDM_ERROR_NONE;
132         }
133
134         ms = ((double)1000.0 / output_data->current_mode->vrefresh) * interval;
135
136         ret = tdm_event_loop_source_timer_update(output_data->timer, ms);
137         if (ret != TDM_ERROR_NONE)
138                 return ret;
139
140         LIST_ADDTAIL(&event_data->link, &output_data->timer_event_list);
141
142         return TDM_ERROR_NONE;
143 }
144
145 static void
146 _tdm_virtual_display_destroy_layer_list(tdm_virtual_data *virtual_data)
147 {
148         tdm_virtual_output_data *o = NULL;
149
150         LIST_FOR_EACH_ENTRY(o, &virtual_data->output_list, link) {
151                 tdm_virtual_layer_data *l = NULL, *ll = NULL;
152                 LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
153                         LIST_DEL(&l->link);
154                         free(l);
155                 }
156         }
157 }
158
159 void
160 tdm_virtual_display_destroy_output_list(tdm_virtual_data *virtual_data)
161 {
162         tdm_virtual_output_data *o = NULL, *oo = NULL;
163
164         if (LIST_IS_EMPTY(&virtual_data->output_list))
165                 return;
166
167         _tdm_virtual_display_destroy_layer_list(virtual_data);
168
169         LIST_FOR_EACH_ENTRY_SAFE(o, oo, &virtual_data->output_list, link) {
170                 LIST_DEL(&o->link);
171
172                 if (!LIST_IS_EMPTY(&o->timer_event_list)) {
173                         tdm_virtual_event_data *e = NULL, *ee = NULL;
174                         LIST_FOR_EACH_ENTRY_SAFE(e, ee, &o->timer_event_list, link) {
175                                 LIST_DEL(&e->link);
176                                 free(e);
177                         }
178                 }
179
180                 if (o->timer)
181                         tdm_event_loop_source_remove(o->timer);
182
183                 if (o->output_modes)
184                         free(o->output_modes);
185                 free(o);
186         }
187 }
188
189 tdm_error
190 virtual_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
191 {
192         RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
193
194         caps->max_layer_count = -1; /* not defined */
195
196         return TDM_ERROR_NONE;
197 }
198
199 tdm_output **
200 virtual_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
201 {
202         tdm_virtual_data *virtual_data = bdata;
203         tdm_virtual_output_data *output_data = NULL;
204         tdm_output **outputs;
205         tdm_error ret;
206         int i;
207
208         RETURN_VAL_IF_FAIL(virtual_data, NULL);
209         RETURN_VAL_IF_FAIL(count, NULL);
210
211         *count = 0;
212         LIST_FOR_EACH_ENTRY(output_data, &virtual_data->output_list, link)
213         (*count)++;
214
215         if (*count == 0) {
216                 ret = TDM_ERROR_NONE;
217                 goto failed_get;
218         }
219
220         /* will be freed in frontend */
221         outputs = calloc(*count, sizeof(tdm_virtual_output_data *));
222         if (!outputs) {
223                 TDM_ERR("failed: alloc memory");
224                 *count = 0;
225                 ret = TDM_ERROR_OUT_OF_MEMORY;
226                 goto failed_get;
227         }
228
229         i = 0;
230         LIST_FOR_EACH_ENTRY(output_data, &virtual_data->output_list, link)
231         outputs[i++] = output_data;
232
233         if (error)
234                 *error = TDM_ERROR_NONE;
235
236         return outputs;
237 failed_get:
238         if (error)
239                 *error = ret;
240         return NULL;
241 }
242
243 tdm_error
244 virtual_display_get_fd(tdm_backend_data *bdata, int *fd)
245 {
246         tdm_virtual_data *virtual_data = bdata;
247
248         RETURN_VAL_IF_FAIL(virtual_data, TDM_ERROR_INVALID_PARAMETER);
249         RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
250
251         *fd = virtual_data->pipe[0];
252
253         return TDM_ERROR_NONE;
254 }
255
256 tdm_error
257 virtual_display_handle_events(tdm_backend_data *bdata)
258 {
259         return TDM_ERROR_NONE;
260 }
261
262 tdm_output *
263 virtual_display_output_create(tdm_backend_data *bdata, const char *name, tdm_error *error)
264 {
265         tdm_virtual_data *virtual_data = bdata;
266         tdm_virtual_output_data *output_data = NULL;
267         tdm_virtual_layer_data *layer_data = NULL;
268         tdm_error ret;
269
270         if (!virtual_data || !name) {
271                 TDM_ERR("invalid parameter");
272                 *error = TDM_ERROR_INVALID_PARAMETER;
273                 return NULL;
274         }
275
276         output_data = calloc(1, sizeof(tdm_virtual_output_data));
277         if (!output_data) {
278                 TDM_ERR("alloc failed");
279                 *error = TDM_ERROR_OUT_OF_MEMORY;
280                 return NULL;
281         }
282
283         LIST_INITHEAD(&output_data->layer_list);
284
285         output_data->virtual_data = virtual_data;
286         output_data->pipe = 0;
287         output_data->connector_type = TDM_OUTPUT_TYPE_Unknown;
288         output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
289
290         if (name)
291                 snprintf(output_data->name, TDM_NAME_LEN, "%s", name);
292         else
293                 snprintf(output_data->name, TDM_NAME_LEN, "unknown");
294
295         output_data->output_modes = calloc(1, sizeof(tdm_output_mode));
296         if (!output_data->output_modes) {
297                 TDM_ERR("alloc failed");
298                 ret = TDM_ERROR_OUT_OF_MEMORY;
299                 goto create_fail;
300         }
301
302         /* default mode */
303         snprintf(output_data->output_modes->name, TDM_NAME_LEN, "640x480");
304         output_data->output_modes->vrefresh = 30;
305         output_data->output_modes->clock = 25200;
306         output_data->output_modes->hdisplay = 640;
307         output_data->output_modes->hsync_start = 656;
308         output_data->output_modes->hsync_end = 752;
309         output_data->output_modes->htotal = 800;
310         output_data->output_modes->hskew = 0;
311         output_data->output_modes->vdisplay = 480;
312         output_data->output_modes->vsync_start = 490;
313         output_data->output_modes->vsync_end = 492;
314         output_data->output_modes->vtotal = 525;
315         output_data->output_modes->vscan = 0;
316         output_data->output_modes->flags = 0;
317         output_data->output_modes->type = 0;
318         output_data->mode_count = 1;
319
320         output_data->timer = tdm_event_loop_add_timer_handler(virtual_data->dpy,
321                                                                                                                   _tdm_virtual_display_cb_timeout,
322                                                                                                                   output_data,
323                                                                                                                   &ret);
324         if (!output_data->timer) goto create_fail;
325
326         LIST_INITHEAD(&output_data->timer_event_list);
327
328         /* The TDM virtual backend output support only one layer. */
329         layer_data = calloc(1, sizeof(tdm_virtual_layer_data));
330         if (!layer_data) {
331                 TDM_ERR("alloc failed");
332                 ret = TDM_ERROR_OUT_OF_MEMORY;
333                 goto create_fail;
334         }
335
336         layer_data->virtual_data = virtual_data;
337         layer_data->output_data = output_data;
338         layer_data->zpos = 0;
339
340         layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
341         output_data->primary_layer = layer_data;
342
343         LIST_ADDTAIL(&output_data->link, &virtual_data->output_list);
344         LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
345
346         ret = tdm_backend_register_output(virtual_data->dpy, output_data);
347         if (ret != TDM_ERROR_NONE) {
348                 LIST_DEL(&output_data->link);
349                 goto create_fail;
350         }
351
352         *error = TDM_ERROR_NONE;
353
354         return output_data;
355
356 create_fail:
357         if (layer_data) free(layer_data);
358         if (output_data->output_modes) free(output_data->output_modes);
359         free(output_data);
360
361         *error = ret;
362
363         return NULL;
364 }
365
366 tdm_error
367 virtual_display_output_destroy(tdm_backend_data *bdata, tdm_output *output)
368 {
369         tdm_virtual_data *virtual_data = bdata;
370         tdm_virtual_output_data *o, *output_data = output;
371         int find = 0;
372
373         RETURN_VAL_IF_FAIL(virtual_data, TDM_ERROR_INVALID_PARAMETER);
374         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
375
376         LIST_FOR_EACH_ENTRY(o, &virtual_data->output_list, link) {
377                 if (o == output_data) {
378                         find = 1;
379                         break;
380                 }
381         }
382
383         if (find) {
384                 tdm_virtual_layer_data *l = NULL, *ll = NULL;
385
386                 tdm_backend_unregister_output(virtual_data->dpy, output);
387
388                 if (!LIST_IS_EMPTY(&o->timer_event_list)) {
389                         tdm_virtual_event_data *e = NULL, *ee = NULL;
390                         LIST_FOR_EACH_ENTRY_SAFE(e, ee, &o->timer_event_list, link) {
391                                 LIST_DEL(&e->link);
392                                 free(e);
393                         }
394                 }
395
396                 if (o->timer)
397                         tdm_event_loop_source_remove(o->timer);
398
399                 LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
400                         LIST_DEL(&l->link);
401                         free(l);
402                 }
403
404                 if (output_data->output_modes)
405                         free(output_data->output_modes);
406
407                 LIST_DEL(&o->link);
408                 free(o);
409         } else
410                 return TDM_ERROR_INVALID_PARAMETER;
411
412         return TDM_ERROR_NONE;
413 }
414
415 tdm_error
416 virtual_output_get_capability(tdm_output *output, tdm_caps_output *caps)
417 {
418         tdm_virtual_output_data *output_data = output;
419         tdm_error ret;
420
421         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
422         RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
423
424         memset(caps, 0, sizeof(tdm_caps_output));
425
426         snprintf(caps->maker, TDM_NAME_LEN, "virtual");
427         snprintf(caps->model, TDM_NAME_LEN, "virtual");
428         snprintf(caps->name, TDM_NAME_LEN, "%s", output_data->name);
429
430         caps->status = output_data->status;
431         caps->type = output_data->connector_type;
432         caps->type_id = 0;
433
434         if (output_data->status == TDM_OUTPUT_CONN_STATUS_CONNECTED ||
435                 output_data->status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
436                 caps->mode_count = output_data->mode_count;
437                 if (output_data->mode_count != 0) {
438                         caps->modes = calloc(output_data->mode_count, sizeof(tdm_output_mode));
439                         if (!caps->modes) {
440                                 ret = TDM_ERROR_OUT_OF_MEMORY;
441                                 TDM_ERR("alloc failed\n");
442                                 goto failed_get;
443                         }
444                         memcpy(caps->modes, output_data->output_modes, output_data->mode_count * sizeof(tdm_output_mode));
445                 }
446
447                 caps->mmWidth = output_data->mmwidth;
448                 caps->mmHeight = output_data->mmheight;
449         } else {
450                 caps->modes = NULL;
451                 caps->mode_count = 0;
452                 caps->mmWidth = 0;
453                 caps->mmHeight = 0;
454         }
455         caps->subpixel = 1;
456
457         caps->min_w = -1;
458         caps->min_h = -1;
459         caps->max_w = -1;
460         caps->max_h = -1;
461         caps->preferred_align = -1;
462
463         caps->prop_count = 0;
464
465         return TDM_ERROR_NONE;
466 failed_get:
467         memset(caps, 0, sizeof(tdm_caps_output));
468         return ret;
469 }
470
471 tdm_layer **
472 virtual_output_get_layers(tdm_output *output,  int *count, tdm_error *error)
473 {
474         tdm_virtual_output_data *output_data = output;
475         tdm_virtual_layer_data *layer_data = NULL;
476         tdm_layer **layers;
477         tdm_error ret;
478         int i;
479
480         RETURN_VAL_IF_FAIL(output_data, NULL);
481         RETURN_VAL_IF_FAIL(count, NULL);
482
483         *count = 0;
484         LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
485         (*count)++;
486
487         if (*count == 0) {
488                 ret = TDM_ERROR_NONE;
489                 goto failed_get;
490         }
491
492         /* will be freed in frontend */
493         layers = calloc(*count, sizeof(tdm_virtual_layer_data *));
494         if (!layers) {
495                 TDM_ERR("failed: alloc memory");
496                 *count = 0;
497                 ret = TDM_ERROR_OUT_OF_MEMORY;
498                 goto failed_get;
499         }
500
501         i = 0;
502         LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
503         layers[i++] = layer_data;
504
505         if (error)
506                 *error = TDM_ERROR_NONE;
507
508         return layers;
509 failed_get:
510         if (error)
511                 *error = ret;
512         return NULL;
513 }
514
515 tdm_error
516 virtual_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data)
517 {
518         tdm_virtual_output_data *output_data = output;
519         tdm_virtual_event_data *event_data;
520         tdm_error ret;
521
522         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
523
524         event_data = calloc(1, sizeof(tdm_virtual_event_data));
525         if (!event_data) {
526                 TDM_ERR("alloc failed");
527                 return TDM_ERROR_OUT_OF_MEMORY;
528         }
529
530         event_data->type = TDM_VIRTUAL_EVENT_TYPE_WAIT;
531         event_data->output_data = output_data;
532         event_data->user_data = user_data;
533
534         ret = _tdm_virtual_display_wait_vblank(output_data, interval, event_data);
535         if (ret != TDM_ERROR_NONE) {
536                 free(event_data);
537                 return ret;
538         }
539
540         return TDM_ERROR_NONE;
541 }
542
543 tdm_error
544 virtual_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func)
545 {
546         tdm_virtual_output_data *output_data = output;
547
548         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
549         RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
550
551         output_data->vblank_func = func;
552
553         return TDM_ERROR_NONE;
554 }
555
556 tdm_error
557 virtual_output_commit(tdm_output *output, int sync, void *user_data)
558 {
559         tdm_virtual_output_data *output_data = output;
560         tdm_virtual_event_data *event_data;
561         tdm_error ret;
562
563         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
564
565         event_data = calloc(1, sizeof(tdm_virtual_event_data));
566         if (!event_data) {
567                 TDM_ERR("alloc failed");
568                 return TDM_ERROR_OUT_OF_MEMORY;
569         }
570
571         event_data->type = TDM_VIRTUAL_EVENT_TYPE_COMMIT;
572         event_data->output_data = output_data;
573         event_data->user_data = user_data;
574
575         ret = _tdm_virtual_display_wait_vblank(output_data, 1, event_data);
576         if (ret != TDM_ERROR_NONE) {
577                 free(event_data);
578                 return ret;
579         }
580
581         return TDM_ERROR_NONE;
582 }
583
584 tdm_error
585 virtual_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func)
586 {
587         tdm_virtual_output_data *output_data = output;
588
589         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
590         RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
591
592         output_data->commit_func = func;
593
594         return TDM_ERROR_NONE;
595 }
596
597 tdm_error
598 virtual_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
599 {
600         tdm_virtual_output_data *output_data = output;
601
602         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
603         RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
604
605         output_data->current_mode = mode;
606         output_data->mode_changed = 1;
607
608         return TDM_ERROR_NONE;
609 }
610
611 tdm_error
612 virtual_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
613 {
614         tdm_virtual_output_data *output_data = output;
615
616         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
617         RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
618
619         *mode = output_data->current_mode;
620
621         return TDM_ERROR_NONE;
622 }
623
624 tdm_error
625 virtual_output_set_available_mode(tdm_output *output, const tdm_output_mode *modes, int count)
626 {
627         tdm_virtual_output_data *output_data = output;
628
629         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
630         RETURN_VAL_IF_FAIL(modes, TDM_ERROR_INVALID_PARAMETER);
631         RETURN_VAL_IF_FAIL(count > 0, TDM_ERROR_INVALID_PARAMETER);
632
633         /* set available mode only permittied disconnect status */
634         RETURN_VAL_IF_FAIL(output_data->status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED, TDM_ERROR_BUSY);
635
636         if (output_data->output_modes)
637                 free(output_data->output_modes);
638         output_data->output_modes = NULL;
639
640         output_data->output_modes = calloc(1, count * sizeof(tdm_output_mode));
641         RETURN_VAL_IF_FAIL(output_data->output_modes != NULL, TDM_ERROR_OUT_OF_MEMORY);
642
643         memcpy(output_data->output_modes, modes, count * sizeof(tdm_output_mode));
644         output_data->mode_count = count;
645
646         return TDM_ERROR_NONE;
647 }
648
649 tdm_error
650 virtual_output_set_physical_size(tdm_output *output, unsigned int mmwidth, unsigned int mmheight)
651 {
652         tdm_virtual_output_data *output_data = output;
653
654         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
655         RETURN_VAL_IF_FAIL(mmwidth != 0, TDM_ERROR_INVALID_PARAMETER);
656         RETURN_VAL_IF_FAIL(mmheight != 0, TDM_ERROR_INVALID_PARAMETER);
657
658         output_data->mmwidth = mmwidth;
659         output_data->mmheight = mmheight;
660
661         return TDM_ERROR_NONE;
662 }
663
664 tdm_error
665 virtual_output_set_connect(tdm_output *output)
666 {
667         tdm_virtual_output_data *output_data = output;
668
669         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
670
671         if (output_data->status == TDM_OUTPUT_CONN_STATUS_CONNECTED ||
672                 output_data->status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED)
673                 return TDM_ERROR_NONE;
674
675         output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
676
677         if (output_data->status_func)
678                 output_data->status_func(output_data, output_data->status,
679                                                                  output_data->status_user_data);
680
681         return TDM_ERROR_NONE;
682 }
683
684 tdm_error
685 virtual_output_set_disconnect(tdm_output *output)
686 {
687         tdm_virtual_output_data *output_data = output;
688
689         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
690
691         if (output_data->status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
692                 return TDM_ERROR_NONE;
693
694         output_data->status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
695
696         if (output_data->status_func)
697                 output_data->status_func(output_data, output_data->status,
698                                                                  output_data->status_user_data);
699
700         return TDM_ERROR_NONE;
701 }
702
703 tdm_error
704 virtual_output_set_status_handler(tdm_output *output,
705                                                                   tdm_output_status_handler func, void *user_data)
706 {
707         tdm_virtual_output_data *output_data = output;
708
709         RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
710         RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
711
712         output_data->status_func = func;
713         output_data->status_user_data = user_data;
714
715         return TDM_ERROR_NONE;
716 }
717
718 tdm_error
719 virtual_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
720 {
721         tdm_virtual_layer_data *layer_data = layer;
722
723         RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
724         RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
725
726         memset(caps, 0, sizeof(tdm_caps_layer));
727
728         caps->capabilities = layer_data->capabilities;
729         caps->zpos = layer_data->zpos;
730
731         caps->format_count = 2;
732         caps->formats = calloc(caps->format_count, sizeof(tbm_format));
733         if (!caps->formats) {
734                 TDM_ERR("alloc failed\n");
735                 free(caps->formats);
736                 memset(caps, 0, sizeof(tdm_caps_layer));
737                 return TDM_ERROR_OUT_OF_MEMORY;
738         }
739
740         caps->formats[0] = TBM_FORMAT_ARGB8888;
741         caps->formats[1] = TBM_FORMAT_XRGB8888;
742
743         caps->prop_count = 0;
744
745         return TDM_ERROR_NONE;
746 }
747
748 tdm_error
749 virtual_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
750 {
751         tdm_virtual_layer_data *layer_data = layer;
752
753         RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
754         RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
755
756         layer_data->info = *info;
757         layer_data->info_changed = 1;
758
759         return TDM_ERROR_NONE;
760 }
761
762 tdm_error
763 virtual_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
764 {
765         tdm_virtual_layer_data *layer_data = layer;
766
767         RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
768         RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
769
770         *info = layer_data->info;
771
772         return TDM_ERROR_NONE;
773 }
774
775 tdm_error
776 virtual_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
777 {
778         tdm_virtual_layer_data *layer_data = layer;
779
780         RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
781         RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
782
783         layer_data->display_buffer = buffer;
784         layer_data->display_buffer_changed = 1;
785
786         return TDM_ERROR_NONE;
787 }
788
789 tdm_error
790 virtual_layer_unset_buffer(tdm_layer *layer)
791 {
792         tdm_virtual_layer_data *layer_data = layer;
793
794         RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
795
796         layer_data->display_buffer = NULL;
797         layer_data->display_buffer_changed = 1;
798
799         return TDM_ERROR_NONE;
800 }