fix tdm_display_get_pp_available_properties function pp conut return error
[platform/core/uifw/libtdm.git] / src / tdm_display.c
1 /**************************************************************************
2
3 libtdm
4
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8          JinYoung Jeon <jy0.jeon@samsung.com>,
9          Taeheon Kim <th908.kim@samsung.com>,
10          YoungJun Cho <yj44.cho@samsung.com>,
11          SooChan Lim <sc1.lim@samsung.com>,
12          Boram Park <sc1.lim@samsung.com>
13
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sub license, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
21
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
24 of the Software.
25
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
34 **************************************************************************/
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "tdm.h"
41 #include "tdm_backend.h"
42 #include "tdm_private.h"
43
44 #define COUNT_MAX   10
45
46 #define DISPLAY_FUNC_ENTRY() \
47     tdm_private_display *private_display; \
48     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
49     TDM_RETURN_VAL_IF_FAIL(dpy != NULL, TDM_ERROR_INVALID_PARAMETER); \
50     private_display = (tdm_private_display*)dpy;
51
52 #define DISPLAY_FUNC_ENTRY_ERROR() \
53     tdm_private_display *private_display; \
54     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
55     TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
56     private_display = (tdm_private_display*)dpy;
57
58 #define OUTPUT_FUNC_ENTRY() \
59     tdm_private_display *private_display; \
60     tdm_private_output *private_output; \
61     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
62     TDM_RETURN_VAL_IF_FAIL(output != NULL, TDM_ERROR_INVALID_PARAMETER); \
63     private_output = (tdm_private_output*)output; \
64     private_display = private_output->private_display
65
66 #define OUTPUT_FUNC_ENTRY_ERROR() \
67     tdm_private_display *private_display; \
68     tdm_private_output *private_output; \
69     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
70     TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
71     private_output = (tdm_private_output*)output; \
72     private_display = private_output->private_display
73
74 #define LAYER_FUNC_ENTRY() \
75     tdm_private_display *private_display; \
76     tdm_private_output *private_output; \
77     tdm_private_layer *private_layer; \
78     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
79     TDM_RETURN_VAL_IF_FAIL(layer != NULL, TDM_ERROR_INVALID_PARAMETER); \
80     private_layer = (tdm_private_layer*)layer; \
81     private_output = private_layer->private_output; \
82     private_display = private_output->private_display
83
84 #define LAYER_FUNC_ENTRY_ERROR() \
85     tdm_private_display *private_display; \
86     tdm_private_output *private_output; \
87     tdm_private_layer *private_layer; \
88     tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\
89     TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(layer != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \
90     private_layer = (tdm_private_layer*)layer; \
91     private_output = private_layer->private_output; \
92     private_display = private_output->private_display
93
94 EXTERN tdm_error
95 tdm_display_get_capabilities(tdm_display *dpy, tdm_display_capability *capabilities)
96 {
97     DISPLAY_FUNC_ENTRY();
98
99     TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
100
101     pthread_mutex_lock(&private_display->lock);
102
103     *capabilities = private_display->capabilities;
104
105     pthread_mutex_unlock(&private_display->lock);
106
107     return ret;
108 }
109
110 EXTERN tdm_error
111 tdm_display_get_pp_capabilities(tdm_display *dpy, tdm_pp_capability *capabilities)
112 {
113     DISPLAY_FUNC_ENTRY();
114
115     TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
116
117     pthread_mutex_lock(&private_display->lock);
118
119     *capabilities = private_display->caps_pp.capabilities;
120
121     pthread_mutex_unlock(&private_display->lock);
122
123     return ret;
124 }
125
126 EXTERN tdm_error
127 tdm_display_get_pp_available_formats(tdm_display *dpy, const tbm_format **formats, int *count)
128 {
129     DISPLAY_FUNC_ENTRY();
130
131     TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
132     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
133
134     pthread_mutex_lock(&private_display->lock);
135
136     *formats = (const tbm_format*)private_display->caps_pp.formats;
137     *count = private_display->caps_pp.format_count;
138
139     pthread_mutex_unlock(&private_display->lock);
140
141     return ret;
142 }
143
144 EXTERN tdm_error
145 tdm_display_get_pp_available_size(tdm_display *dpy, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align)
146 {
147     DISPLAY_FUNC_ENTRY();
148
149     pthread_mutex_lock(&private_display->lock);
150
151     if (min_w)
152         *min_w = private_display->caps_pp.min_w;
153     if (min_h)
154         *min_h = private_display->caps_pp.min_h;
155     if (max_w)
156         *max_w = private_display->caps_pp.max_w;
157     if (max_h)
158         *max_h = private_display->caps_pp.max_h;
159     if (preferred_align)
160         *preferred_align = private_display->caps_pp.preferred_align;
161
162     pthread_mutex_unlock(&private_display->lock);
163
164     return ret;
165 }
166
167 EXTERN tdm_error
168 tdm_display_get_pp_available_properties(tdm_display *dpy, const tdm_prop **props, int *count)
169 {
170     DISPLAY_FUNC_ENTRY();
171
172     TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
173     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
174
175     pthread_mutex_lock(&private_display->lock);
176
177     *props = (const tdm_prop*)private_display->caps_pp.props;
178     *count = private_display->caps_pp.prop_count;
179
180     pthread_mutex_unlock(&private_display->lock);
181
182     return ret;
183 }
184
185 EXTERN tdm_error
186 tdm_display_get_capture_capabilities(tdm_display *dpy, tdm_capture_capability *capabilities)
187 {
188     DISPLAY_FUNC_ENTRY();
189
190     TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
191
192     pthread_mutex_lock(&private_display->lock);
193
194     *capabilities = private_display->caps_capture.capabilities;
195
196     pthread_mutex_unlock(&private_display->lock);
197
198     return ret;
199 }
200
201 EXTERN tdm_error
202 tdm_display_get_catpure_available_formats(tdm_display *dpy, const tbm_format **formats, int *count)
203 {
204     DISPLAY_FUNC_ENTRY();
205
206     TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
207     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
208
209     pthread_mutex_lock(&private_display->lock);
210
211     *formats = (const tbm_format*)private_display->caps_capture.formats;
212     *count = private_display->caps_capture.format_count;
213
214     pthread_mutex_unlock(&private_display->lock);
215
216     return ret;
217 }
218
219 EXTERN tdm_error
220 tdm_display_get_output_count(tdm_display *dpy, int *count)
221 {
222     tdm_private_output *private_output = NULL;
223
224     DISPLAY_FUNC_ENTRY();
225
226     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
227
228     pthread_mutex_lock(&private_display->lock);
229
230     *count = 0;
231     LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
232         (*count)++;
233
234     if (*count == 0)
235     {
236         pthread_mutex_unlock(&private_display->lock);
237         return TDM_ERROR_NONE;
238     }
239
240     pthread_mutex_unlock(&private_display->lock);
241
242     return ret;
243 }
244
245
246 EXTERN const tdm_output*
247 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
248 {
249     tdm_private_output *private_output = NULL;
250     int i = 0;
251
252     DISPLAY_FUNC_ENTRY_ERROR();
253
254     pthread_mutex_lock(&private_display->lock);
255
256     if (error)
257         *error = TDM_ERROR_NONE;
258
259     i = 0;
260     LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
261     {
262         if (i == index)
263         {
264             pthread_mutex_unlock(&private_display->lock);
265             return (const tdm_output*)private_output;
266         }
267         i++;
268     }
269
270     pthread_mutex_unlock(&private_display->lock);
271
272     return NULL;
273 }
274
275 EXTERN tdm_error
276 tdm_display_get_fd(tdm_display *dpy, int *fd)
277 {
278     tdm_func_display *func_display;
279     DISPLAY_FUNC_ENTRY();
280
281     TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
282
283     pthread_mutex_lock(&private_display->lock);
284
285     func_display = &private_display->func_display;
286
287     if (!func_display->display_get_fd)
288     {
289         pthread_mutex_unlock(&private_display->lock);
290         return TDM_ERROR_NONE;
291     }
292
293     ret = func_display->display_get_fd(private_display->bdata, fd);
294
295     pthread_mutex_unlock(&private_display->lock);
296
297     return ret;
298 }
299
300 EXTERN tdm_error
301 tdm_display_handle_events(tdm_display *dpy)
302 {
303     tdm_func_display *func_display;
304     DISPLAY_FUNC_ENTRY();
305
306     pthread_mutex_lock(&private_display->lock);
307
308     func_display = &private_display->func_display;
309
310     if (!func_display->display_handle_events)
311     {
312         pthread_mutex_unlock(&private_display->lock);
313         return TDM_ERROR_NONE;
314     }
315
316     ret = func_display->display_handle_events(private_display->bdata);
317
318     pthread_mutex_unlock(&private_display->lock);
319
320     return ret;
321 }
322
323 EXTERN tdm_pp*
324 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
325 {
326     tdm_pp *pp;
327
328     DISPLAY_FUNC_ENTRY_ERROR();
329
330     pthread_mutex_lock(&private_display->lock);
331
332     pp = (tdm_pp*)tdm_pp_create_internal(private_display, error);
333
334     pthread_mutex_unlock(&private_display->lock);
335
336     return pp;
337 }
338
339 EXTERN tdm_error
340 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
341 {
342     OUTPUT_FUNC_ENTRY();
343
344     TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
345
346     pthread_mutex_lock(&private_display->lock);
347
348     *status = private_output->caps.status;
349
350     pthread_mutex_unlock(&private_display->lock);
351
352     return ret;
353 }
354
355 EXTERN tdm_error
356 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
357 {
358     OUTPUT_FUNC_ENTRY();
359
360     TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
361
362     pthread_mutex_lock(&private_display->lock);
363
364     *type = private_output->caps.type;
365
366     pthread_mutex_unlock(&private_display->lock);
367
368     return ret;
369 }
370
371 EXTERN tdm_error
372 tdm_output_get_layer_count(tdm_output *output, int *count)
373 {
374     tdm_private_layer *private_layer = NULL;
375
376     OUTPUT_FUNC_ENTRY();
377
378     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
379
380     pthread_mutex_lock(&private_display->lock);
381
382     *count = 0;
383     LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
384         (*count)++;
385     if (*count == 0)
386     {
387         pthread_mutex_unlock(&private_display->lock);
388         return TDM_ERROR_NONE;
389     }
390
391     pthread_mutex_unlock(&private_display->lock);
392
393     return ret;
394 }
395
396
397 EXTERN const tdm_layer*
398 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
399 {
400     tdm_private_layer *private_layer = NULL;
401     int i = 0;
402
403     OUTPUT_FUNC_ENTRY_ERROR();
404
405     pthread_mutex_lock(&private_display->lock);
406
407     if (error)
408         *error = TDM_ERROR_NONE;
409
410     LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
411     {
412         if (i == index)
413         {
414             pthread_mutex_unlock(&private_display->lock);
415             return private_layer;
416         }
417         i++;
418     }
419
420     pthread_mutex_unlock(&private_display->lock);
421
422     return NULL;
423 }
424
425 EXTERN tdm_error
426 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props, int *count)
427 {
428     OUTPUT_FUNC_ENTRY();
429
430     TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
431     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
432
433     pthread_mutex_lock(&private_display->lock);
434
435     *props = (const tdm_prop*)private_output->caps.props;
436     *count = private_output->caps.prop_count;
437
438     pthread_mutex_unlock(&private_display->lock);
439
440     return ret;
441 }
442
443 EXTERN tdm_error
444 tdm_output_get_available_modes(tdm_output *output, const tdm_output_mode **modes, int *count)
445 {
446     OUTPUT_FUNC_ENTRY();
447
448     TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
449     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
450
451     pthread_mutex_lock(&private_display->lock);
452
453     *modes = (const tdm_output_mode*)private_output->caps.modes;
454     *count = private_output->caps.mode_count;
455
456     pthread_mutex_unlock(&private_display->lock);
457
458     return ret;
459 }
460
461 EXTERN tdm_error
462 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h, int *max_w, int *max_h, int *preferred_align)
463 {
464     OUTPUT_FUNC_ENTRY();
465
466     pthread_mutex_lock(&private_display->lock);
467
468     if (min_w)
469         *min_w = private_output->caps.min_w;
470     if (min_h)
471         *min_h = private_output->caps.min_h;
472     if (max_w)
473         *max_w = private_output->caps.max_w;
474     if (max_h)
475         *max_h = private_output->caps.max_h;
476     if (preferred_align)
477         *preferred_align = private_output->caps.preferred_align;
478
479     pthread_mutex_unlock(&private_display->lock);
480
481     return ret;
482 }
483
484 EXTERN tdm_error
485 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth, unsigned int *mmHeight)
486 {
487     OUTPUT_FUNC_ENTRY();
488
489     pthread_mutex_lock(&private_display->lock);
490
491     if (mmWidth)
492         *mmWidth = private_output->caps.mmWidth;
493     if (mmHeight)
494         *mmHeight = private_output->caps.mmHeight;
495
496     pthread_mutex_unlock(&private_display->lock);
497
498     return ret;
499 }
500
501 EXTERN tdm_error
502 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
503 {
504     OUTPUT_FUNC_ENTRY();
505
506     pthread_mutex_lock(&private_display->lock);
507
508     if (subpixel)
509         *subpixel = private_output->caps.subpixel;
510
511     pthread_mutex_unlock(&private_display->lock);
512
513     return ret;
514 }
515
516 EXTERN tdm_error
517 tdm_output_set_property(tdm_output *output, unsigned int id, tdm_value value)
518 {
519     tdm_func_display *func_display;
520     OUTPUT_FUNC_ENTRY();
521
522     pthread_mutex_lock(&private_display->lock);
523
524     func_display = &private_display->func_display;
525
526     if (!func_display->output_set_property)
527     {
528         pthread_mutex_unlock(&private_display->lock);
529         return TDM_ERROR_NONE;
530     }
531
532     ret = func_display->output_set_property(private_output->output, id, value);
533
534     pthread_mutex_unlock(&private_display->lock);
535
536     return ret;
537 }
538
539 EXTERN tdm_error
540 tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value)
541 {
542     tdm_func_display *func_display;
543     OUTPUT_FUNC_ENTRY();
544
545     TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
546
547     pthread_mutex_lock(&private_display->lock);
548
549     func_display = &private_display->func_display;
550
551     if (!func_display->output_get_property)
552     {
553         pthread_mutex_unlock(&private_display->lock);
554         return TDM_ERROR_NONE;
555     }
556
557     ret = func_display->output_get_property(private_output->output, id, value);
558
559     pthread_mutex_unlock(&private_display->lock);
560
561     return ret;
562 }
563
564 static void
565 _tdm_output_cb_vblank(tdm_output *output, unsigned int sequence,
566                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
567 {
568     tdm_private_output *private_output = output;
569     tdm_private_vblank_handler *vblank_handler = user_data;
570
571     TDM_RETURN_IF_FAIL(private_output);
572     TDM_RETURN_IF_FAIL(vblank_handler);
573
574     if (vblank_handler->func)
575         vblank_handler->func(private_output, sequence, tv_sec, tv_usec, vblank_handler->user_data);
576
577     LIST_DEL(&vblank_handler->link);
578     free(vblank_handler);
579 }
580
581 static void
582 _tdm_output_cb_commit(tdm_output *output, unsigned int sequence,
583                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
584 {
585     tdm_private_output *private_output = output;
586     tdm_private_commit_handler *commit_handler = user_data;
587
588     TDM_RETURN_IF_FAIL(private_output);
589     TDM_RETURN_IF_FAIL(commit_handler);
590
591     if (commit_handler->func)
592         commit_handler->func(private_output, sequence, tv_sec, tv_usec, commit_handler->user_data);
593
594     LIST_DEL(&commit_handler->link);
595     free(commit_handler);
596 }
597
598 EXTERN tdm_error
599 tdm_output_wait_vblank(tdm_output *output, int interval, int sync, tdm_output_vblank_handler func, void *user_data)
600 {
601     tdm_func_display *func_display;
602     tdm_private_vblank_handler *vblank_handler;
603     OUTPUT_FUNC_ENTRY();
604
605     pthread_mutex_lock(&private_display->lock);
606
607     func_display = &private_display->func_display;
608
609     if (!func_display->output_wait_vblank)
610     {
611         pthread_mutex_unlock(&private_display->lock);
612         return TDM_ERROR_NONE;
613     }
614
615     vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
616     if (!vblank_handler)
617     {
618         TDM_ERR("failed: alloc memory");
619         pthread_mutex_unlock(&private_display->lock);
620         return TDM_ERROR_OUT_OF_MEMORY;
621     }
622
623     LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
624     vblank_handler->func = func;
625     vblank_handler->user_data = user_data;
626
627     ret = func_display->output_wait_vblank(private_output->output, interval, sync, vblank_handler);
628     if (ret != TDM_ERROR_NONE)
629     {
630         pthread_mutex_unlock(&private_display->lock);
631         return ret;
632     }
633
634     if (!private_output->regist_vblank_cb)
635     {
636         private_output->regist_vblank_cb = 1;
637         ret = func_display->output_set_vblank_handler(private_output->output, _tdm_output_cb_vblank);
638     }
639
640     pthread_mutex_unlock(&private_display->lock);
641
642     return ret;
643 }
644
645 EXTERN tdm_error
646 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data)
647 {
648     tdm_func_display *func_display;
649     tdm_private_commit_handler *commit_handler;
650     OUTPUT_FUNC_ENTRY();
651
652     pthread_mutex_lock(&private_display->lock);
653
654     func_display = &private_display->func_display;
655
656     if (!func_display->output_commit)
657     {
658         pthread_mutex_unlock(&private_display->lock);
659         return TDM_ERROR_NONE;
660     }
661
662     commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
663     if (!commit_handler)
664     {
665         TDM_ERR("failed: alloc memory");
666         pthread_mutex_unlock(&private_display->lock);
667         return TDM_ERROR_OUT_OF_MEMORY;
668     }
669
670     LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
671     commit_handler->func = func;
672     commit_handler->user_data = user_data;
673
674     ret = func_display->output_commit(private_output->output, sync, commit_handler);
675     if (ret != TDM_ERROR_NONE)
676     {
677         pthread_mutex_unlock(&private_display->lock);
678         return ret;
679     }
680
681     if (!private_output->regist_commit_cb)
682     {
683         private_output->regist_commit_cb = 1;
684         ret = func_display->output_set_commit_handler(private_output->output, _tdm_output_cb_commit);
685     }
686
687     pthread_mutex_unlock(&private_display->lock);
688
689     return ret;
690 }
691
692 EXTERN tdm_error
693 tdm_output_set_mode(tdm_output *output, tdm_output_mode *mode)
694 {
695     tdm_func_display *func_display;
696     OUTPUT_FUNC_ENTRY();
697
698     TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
699
700     pthread_mutex_lock(&private_display->lock);
701
702     func_display = &private_display->func_display;
703
704     if (!func_display->output_set_mode)
705     {
706         pthread_mutex_unlock(&private_display->lock);
707         return TDM_ERROR_NONE;
708     }
709
710     ret = func_display->output_set_mode(private_output->output, mode);
711
712     pthread_mutex_unlock(&private_display->lock);
713
714     return ret;
715 }
716
717 EXTERN tdm_error
718 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
719 {
720     tdm_func_display *func_display;
721     OUTPUT_FUNC_ENTRY();
722
723     TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
724
725     pthread_mutex_lock(&private_display->lock);
726
727     func_display = &private_display->func_display;
728
729     if (!func_display->output_get_mode)
730     {
731         pthread_mutex_unlock(&private_display->lock);
732         return TDM_ERROR_NONE;
733     }
734
735     ret = func_display->output_get_mode(private_output->output, mode);
736
737     pthread_mutex_unlock(&private_display->lock);
738
739     return ret;
740 }
741
742 EXTERN tdm_error
743 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
744 {
745     tdm_func_display *func_display;
746     OUTPUT_FUNC_ENTRY();
747
748     TDM_RETURN_VAL_IF_FAIL(dpms_value >= TDM_OUTPUT_DPMS_ON, TDM_ERROR_INVALID_PARAMETER);
749     TDM_RETURN_VAL_IF_FAIL(dpms_value < TDM_OUTPUT_DPMS_MAX, TDM_ERROR_INVALID_PARAMETER);
750
751     pthread_mutex_lock(&private_display->lock);
752
753     func_display = &private_display->func_display;
754
755     if (!func_display->output_set_dpms)
756     {
757         pthread_mutex_unlock(&private_display->lock);
758         return TDM_ERROR_NONE;
759     }
760
761     ret = func_display->output_set_dpms(private_output->output, dpms_value);
762
763     pthread_mutex_unlock(&private_display->lock);
764
765     return ret;
766 }
767
768 EXTERN tdm_error
769 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
770 {
771     tdm_func_display *func_display;
772     OUTPUT_FUNC_ENTRY();
773
774     TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
775
776     pthread_mutex_lock(&private_display->lock);
777
778     func_display = &private_display->func_display;
779
780     if (!func_display->output_get_dpms)
781     {
782         pthread_mutex_unlock(&private_display->lock);
783         return TDM_ERROR_NONE;
784     }
785
786     ret = func_display->output_get_dpms(private_output->output, dpms_value);
787
788     pthread_mutex_unlock(&private_display->lock);
789
790     return ret;
791 }
792
793 EXTERN tdm_capture*
794 tdm_output_create_capture(tdm_output *output, tdm_error *error)
795 {
796     tdm_capture *capture = NULL;
797
798     OUTPUT_FUNC_ENTRY_ERROR();
799
800     pthread_mutex_lock(&private_display->lock);
801
802     capture = (tdm_capture*)tdm_capture_create_output_internal(private_output, error);
803
804     pthread_mutex_unlock(&private_display->lock);
805
806     return capture;
807 }
808
809 EXTERN tdm_error
810 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
811 {
812     LAYER_FUNC_ENTRY();
813
814     TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
815
816     pthread_mutex_lock(&private_display->lock);
817
818     *capabilities = private_layer->caps.capabilities;
819
820     pthread_mutex_unlock(&private_display->lock);
821
822     return ret;
823 }
824
825 EXTERN tdm_error
826 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
827 {
828     LAYER_FUNC_ENTRY();
829
830     TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
831     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
832
833     pthread_mutex_lock(&private_display->lock);
834
835     *formats = (const tbm_format*)private_layer->caps.formats;
836     *count = private_layer->caps.format_count;
837
838     pthread_mutex_unlock(&private_display->lock);
839
840     return ret;
841 }
842
843 EXTERN tdm_error
844 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
845 {
846     LAYER_FUNC_ENTRY();
847
848     TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
849     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
850
851     pthread_mutex_lock(&private_display->lock);
852
853     *props = (const tdm_prop*)private_output->caps.props;
854     *count = private_output->caps.prop_count;
855
856     pthread_mutex_unlock(&private_display->lock);
857
858     return ret;
859 }
860
861 EXTERN tdm_error
862 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
863 {
864     LAYER_FUNC_ENTRY();
865
866     TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
867
868     pthread_mutex_lock(&private_display->lock);
869
870     *zpos = private_layer->caps.zpos;
871
872     pthread_mutex_unlock(&private_display->lock);
873
874     return ret;
875 }
876
877 EXTERN tdm_error
878 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
879 {
880     tdm_func_display *func_display;
881     LAYER_FUNC_ENTRY();
882
883     pthread_mutex_lock(&private_display->lock);
884
885     func_display = &private_display->func_display;
886
887     if (!func_display->layer_set_property)
888     {
889         pthread_mutex_unlock(&private_display->lock);
890         return TDM_ERROR_NONE;
891     }
892
893     ret = func_display->layer_set_property(private_layer->layer, id, value);
894
895     pthread_mutex_unlock(&private_display->lock);
896
897     return ret;
898 }
899
900 EXTERN tdm_error
901 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
902 {
903     tdm_func_display *func_display;
904     LAYER_FUNC_ENTRY();
905
906     TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
907
908     pthread_mutex_lock(&private_display->lock);
909
910     func_display = &private_display->func_display;
911
912     if (!func_display->layer_get_property)
913     {
914         pthread_mutex_unlock(&private_display->lock);
915         return TDM_ERROR_NONE;
916     }
917
918     ret = func_display->layer_get_property(private_layer->layer, id, value);
919
920     pthread_mutex_unlock(&private_display->lock);
921
922     return ret;
923 }
924
925 EXTERN tdm_error
926 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
927 {
928     tdm_func_display *func_display;
929     LAYER_FUNC_ENTRY();
930
931     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
932
933     pthread_mutex_lock(&private_display->lock);
934
935     func_display = &private_display->func_display;
936
937     if (!func_display->layer_set_info)
938     {
939         pthread_mutex_unlock(&private_display->lock);
940         return TDM_ERROR_NONE;
941     }
942
943     ret = func_display->layer_set_info(private_layer->layer, info);
944
945     pthread_mutex_unlock(&private_display->lock);
946
947     return ret;
948 }
949
950 EXTERN tdm_error
951 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
952 {
953     tdm_func_display *func_display;
954     LAYER_FUNC_ENTRY();
955
956     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
957
958     pthread_mutex_lock(&private_display->lock);
959
960     func_display = &private_display->func_display;
961
962     if (!func_display->layer_get_info)
963     {
964         pthread_mutex_unlock(&private_display->lock);
965         return TDM_ERROR_NONE;
966     }
967
968     ret = func_display->layer_get_info(private_layer->layer, info);
969
970     pthread_mutex_unlock(&private_display->lock);
971
972     return ret;
973 }
974
975 EXTERN tdm_error
976 tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer)
977 {
978     tdm_func_display *func_display;
979     LAYER_FUNC_ENTRY();
980
981     TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
982
983     pthread_mutex_lock(&private_display->lock);
984
985     func_display = &private_display->func_display;
986
987     if (!func_display->layer_set_buffer)
988     {
989         pthread_mutex_unlock(&private_display->lock);
990         return TDM_ERROR_NONE;
991     }
992
993     //TODO
994     tdm_buffer_ref_backend(buffer);
995     ret = func_display->layer_set_buffer(private_layer->layer,
996                                          tdm_buffer_get_surface(buffer));
997     tdm_buffer_unref_backend(buffer);
998
999     pthread_mutex_unlock(&private_display->lock);
1000
1001     return ret;
1002 }
1003
1004 EXTERN tdm_error
1005 tdm_layer_unset_buffer(tdm_layer *layer)
1006 {
1007     tdm_func_display *func_display;
1008     LAYER_FUNC_ENTRY();
1009
1010     pthread_mutex_lock(&private_display->lock);
1011
1012     func_display = &private_display->func_display;
1013
1014     if (!func_display->layer_unset_buffer)
1015     {
1016         pthread_mutex_unlock(&private_display->lock);
1017         return TDM_ERROR_NONE;
1018     }
1019
1020     ret = func_display->layer_unset_buffer(private_layer->layer);
1021
1022     pthread_mutex_unlock(&private_display->lock);
1023
1024     return ret;
1025 }
1026
1027 EXTERN tdm_capture*
1028 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1029 {
1030     tdm_capture *capture = NULL;
1031
1032     LAYER_FUNC_ENTRY_ERROR();
1033
1034     pthread_mutex_lock(&private_display->lock);
1035
1036     capture = (tdm_capture*)tdm_capture_create_layer_internal(private_layer, error);
1037
1038     pthread_mutex_unlock(&private_display->lock);
1039
1040     return capture;
1041 }