remove private_display_backend variable
[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,
146                                   int *max_w, int *max_h, int *preferred_align)
147 {
148     DISPLAY_FUNC_ENTRY();
149
150     pthread_mutex_lock(&private_display->lock);
151
152     if (min_w)
153         *min_w = private_display->caps_pp.min_w;
154     if (min_h)
155         *min_h = private_display->caps_pp.min_h;
156     if (max_w)
157         *max_w = private_display->caps_pp.max_w;
158     if (max_h)
159         *max_h = private_display->caps_pp.max_h;
160     if (preferred_align)
161         *preferred_align = private_display->caps_pp.preferred_align;
162
163     pthread_mutex_unlock(&private_display->lock);
164
165     return ret;
166 }
167
168 EXTERN tdm_error
169 tdm_display_get_capture_capabilities(tdm_display *dpy, tdm_capture_capability *capabilities)
170 {
171     DISPLAY_FUNC_ENTRY();
172
173     TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
174
175     pthread_mutex_lock(&private_display->lock);
176
177     *capabilities = private_display->caps_capture.capabilities;
178
179     pthread_mutex_unlock(&private_display->lock);
180
181     return ret;
182 }
183
184 EXTERN tdm_error
185 tdm_display_get_catpure_available_formats(tdm_display *dpy, const tbm_format **formats, int *count)
186 {
187     DISPLAY_FUNC_ENTRY();
188
189     TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER);
190     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
191
192     pthread_mutex_lock(&private_display->lock);
193
194     *formats = (const tbm_format*)private_display->caps_capture.formats;
195     *count = private_display->caps_capture.format_count;
196
197     pthread_mutex_unlock(&private_display->lock);
198
199     return ret;
200 }
201
202 EXTERN tdm_error
203 tdm_display_get_output_count(tdm_display *dpy, int *count)
204 {
205     tdm_private_output *private_output = NULL;
206
207     DISPLAY_FUNC_ENTRY();
208
209     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
210
211     pthread_mutex_lock(&private_display->lock);
212
213     *count = 0;
214     LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
215         (*count)++;
216
217     if (*count == 0)
218     {
219         pthread_mutex_unlock(&private_display->lock);
220         return TDM_ERROR_NONE;
221     }
222
223     pthread_mutex_unlock(&private_display->lock);
224
225     return ret;
226 }
227
228
229 EXTERN const tdm_output*
230 tdm_display_get_output(tdm_display *dpy, int index, tdm_error *error)
231 {
232     tdm_private_output *private_output = NULL;
233     int i = 0;
234
235     DISPLAY_FUNC_ENTRY_ERROR();
236
237     pthread_mutex_lock(&private_display->lock);
238
239     if (error)
240         *error = TDM_ERROR_NONE;
241
242     i = 0;
243     LIST_FOR_EACH_ENTRY(private_output, &private_display->output_list, link)
244     {
245         if (i == index)
246         {
247             pthread_mutex_unlock(&private_display->lock);
248             return (const tdm_output*)private_output;
249         }
250         i++;
251     }
252
253     pthread_mutex_unlock(&private_display->lock);
254
255     return NULL;
256 }
257
258 EXTERN tdm_error
259 tdm_display_get_fd(tdm_display *dpy, int *fd)
260 {
261     tdm_func_display *func_display;
262     DISPLAY_FUNC_ENTRY();
263
264     TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_ERROR_INVALID_PARAMETER);
265
266     pthread_mutex_lock(&private_display->lock);
267
268     func_display = &private_display->func_display;
269
270     if (!func_display->display_get_fd)
271     {
272         pthread_mutex_unlock(&private_display->lock);
273         return TDM_ERROR_NONE;
274     }
275
276     ret = func_display->display_get_fd(private_display->bdata, fd);
277
278     pthread_mutex_unlock(&private_display->lock);
279
280     return ret;
281 }
282
283 EXTERN tdm_error
284 tdm_display_handle_events(tdm_display *dpy)
285 {
286     tdm_func_display *func_display;
287     DISPLAY_FUNC_ENTRY();
288
289     pthread_mutex_lock(&private_display->lock);
290
291     func_display = &private_display->func_display;
292
293     if (!func_display->display_handle_events)
294     {
295         pthread_mutex_unlock(&private_display->lock);
296         return TDM_ERROR_NONE;
297     }
298
299     ret = func_display->display_handle_events(private_display->bdata);
300
301     pthread_mutex_unlock(&private_display->lock);
302
303     return ret;
304 }
305
306 EXTERN tdm_pp*
307 tdm_display_create_pp(tdm_display *dpy, tdm_error *error)
308 {
309     tdm_pp *pp;
310
311     DISPLAY_FUNC_ENTRY_ERROR();
312
313     pthread_mutex_lock(&private_display->lock);
314
315     pp = (tdm_pp*)tdm_pp_create_internal(private_display, error);
316
317     pthread_mutex_unlock(&private_display->lock);
318
319     return pp;
320 }
321
322 EXTERN tdm_error
323 tdm_output_get_conn_status(tdm_output *output, tdm_output_conn_status *status)
324 {
325     OUTPUT_FUNC_ENTRY();
326
327     TDM_RETURN_VAL_IF_FAIL(status != NULL, TDM_ERROR_INVALID_PARAMETER);
328
329     pthread_mutex_lock(&private_display->lock);
330
331     *status = private_output->caps.status;
332
333     pthread_mutex_unlock(&private_display->lock);
334
335     return ret;
336 }
337
338 EXTERN tdm_error
339 tdm_output_get_output_type(tdm_output *output, tdm_output_type *type)
340 {
341     OUTPUT_FUNC_ENTRY();
342
343     TDM_RETURN_VAL_IF_FAIL(type != NULL, TDM_ERROR_INVALID_PARAMETER);
344
345     pthread_mutex_lock(&private_display->lock);
346
347     *type = private_output->caps.type;
348
349     pthread_mutex_unlock(&private_display->lock);
350
351     return ret;
352 }
353
354 EXTERN tdm_error
355 tdm_output_get_layer_count(tdm_output *output, int *count)
356 {
357     tdm_private_layer *private_layer = NULL;
358
359     OUTPUT_FUNC_ENTRY();
360
361     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
362
363     pthread_mutex_lock(&private_display->lock);
364
365     *count = 0;
366     LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
367         (*count)++;
368     if (*count == 0)
369     {
370         pthread_mutex_unlock(&private_display->lock);
371         return TDM_ERROR_NONE;
372     }
373
374     pthread_mutex_unlock(&private_display->lock);
375
376     return ret;
377 }
378
379
380 EXTERN const tdm_layer*
381 tdm_output_get_layer(tdm_output *output, int index, tdm_error *error)
382 {
383     tdm_private_layer *private_layer = NULL;
384     int i = 0;
385
386     OUTPUT_FUNC_ENTRY_ERROR();
387
388     pthread_mutex_lock(&private_display->lock);
389
390     if (error)
391         *error = TDM_ERROR_NONE;
392
393     LIST_FOR_EACH_ENTRY(private_layer, &private_output->layer_list, link)
394     {
395         if (i == index)
396         {
397             pthread_mutex_unlock(&private_display->lock);
398             return private_layer;
399         }
400         i++;
401     }
402
403     pthread_mutex_unlock(&private_display->lock);
404
405     return NULL;
406 }
407
408 EXTERN tdm_error
409 tdm_output_get_available_properties(tdm_output *output, const tdm_prop **props, int *count)
410 {
411     OUTPUT_FUNC_ENTRY();
412
413     TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
414     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
415
416     pthread_mutex_lock(&private_display->lock);
417
418     *props = (const tdm_prop*)private_output->caps.props;
419     *count = private_output->caps.prop_count;
420
421     pthread_mutex_unlock(&private_display->lock);
422
423     return ret;
424 }
425
426 EXTERN tdm_error
427 tdm_output_get_available_modes(tdm_output *output, const tdm_output_mode **modes, int *count)
428 {
429     OUTPUT_FUNC_ENTRY();
430
431     TDM_RETURN_VAL_IF_FAIL(modes != NULL, TDM_ERROR_INVALID_PARAMETER);
432     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
433
434     pthread_mutex_lock(&private_display->lock);
435
436     *modes = (const tdm_output_mode*)private_output->caps.modes;
437     *count = private_output->caps.mode_count;
438
439     pthread_mutex_unlock(&private_display->lock);
440
441     return ret;
442 }
443
444 EXTERN tdm_error
445 tdm_output_get_available_size(tdm_output *output, int *min_w, int *min_h,
446                               int *max_w, int *max_h, int *preferred_align)
447 {
448     OUTPUT_FUNC_ENTRY();
449
450     pthread_mutex_lock(&private_display->lock);
451
452     if (min_w)
453         *min_w = private_output->caps.min_w;
454     if (min_h)
455         *min_h = private_output->caps.min_h;
456     if (max_w)
457         *max_w = private_output->caps.max_w;
458     if (max_h)
459         *max_h = private_output->caps.max_h;
460     if (preferred_align)
461         *preferred_align = private_output->caps.preferred_align;
462
463     pthread_mutex_unlock(&private_display->lock);
464
465     return ret;
466 }
467
468 EXTERN tdm_error
469 tdm_output_get_physical_size(tdm_output *output, unsigned int *mmWidth, unsigned int *mmHeight)
470 {
471     OUTPUT_FUNC_ENTRY();
472
473     pthread_mutex_lock(&private_display->lock);
474
475     if (mmWidth)
476         *mmWidth = private_output->caps.mmWidth;
477     if (mmHeight)
478         *mmHeight = private_output->caps.mmHeight;
479
480     pthread_mutex_unlock(&private_display->lock);
481
482     return ret;
483 }
484
485 EXTERN tdm_error
486 tdm_output_get_subpixel(tdm_output *output, unsigned int *subpixel)
487 {
488     OUTPUT_FUNC_ENTRY();
489     TDM_RETURN_VAL_IF_FAIL(subpixel != NULL, TDM_ERROR_INVALID_PARAMETER);
490
491     pthread_mutex_lock(&private_display->lock);
492
493     *subpixel = private_output->caps.subpixel;
494
495     pthread_mutex_unlock(&private_display->lock);
496
497     return ret;
498 }
499
500 EXTERN tdm_error
501 tdm_output_get_pipe(tdm_output *output, unsigned int *pipe)
502 {
503     OUTPUT_FUNC_ENTRY();
504     TDM_RETURN_VAL_IF_FAIL(pipe != NULL, TDM_ERROR_INVALID_PARAMETER);
505
506     pthread_mutex_lock(&private_display->lock);
507
508     *pipe = private_output->pipe;
509
510     pthread_mutex_unlock(&private_display->lock);
511
512     return ret;
513 }
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_backend, 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_backend, 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_backend, unsigned int sequence,
566                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
567 {
568     tdm_private_vblank_handler *vblank_handler = user_data;
569     tdm_private_display *private_display;
570
571     TDM_RETURN_IF_FAIL(vblank_handler);
572
573     private_display = vblank_handler->private_output->private_display;
574
575     pthread_mutex_unlock(&private_display->lock);
576
577     if (vblank_handler->func)
578         vblank_handler->func(vblank_handler->private_output, sequence,
579                              tv_sec, tv_usec, vblank_handler->user_data);
580
581     pthread_mutex_lock(&private_display->lock);
582
583     LIST_DEL(&vblank_handler->link);
584     free(vblank_handler);
585 }
586
587 static void
588 _tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
589                       unsigned int tv_sec, unsigned int tv_usec, void *user_data)
590 {
591     tdm_private_commit_handler *commit_handler = user_data;
592     tdm_private_display *private_display;
593
594     TDM_RETURN_IF_FAIL(commit_handler);
595
596     private_display = commit_handler->private_output->private_display;
597
598     pthread_mutex_unlock(&private_display->lock);
599
600     if (commit_handler->func)
601         commit_handler->func(commit_handler->private_output, sequence,
602                              tv_sec, tv_usec, commit_handler->user_data);
603
604     pthread_mutex_lock(&private_display->lock);
605
606     LIST_DEL(&commit_handler->link);
607     free(commit_handler);
608 }
609
610 EXTERN tdm_error
611 tdm_output_wait_vblank(tdm_output *output, int interval, int sync,
612                        tdm_output_vblank_handler func, void *user_data)
613 {
614     tdm_func_display *func_display;
615     tdm_private_vblank_handler *vblank_handler;
616     OUTPUT_FUNC_ENTRY();
617
618     pthread_mutex_lock(&private_display->lock);
619
620     func_display = &private_display->func_display;
621
622     if (!func_display->output_wait_vblank)
623     {
624         pthread_mutex_unlock(&private_display->lock);
625         return TDM_ERROR_NONE;
626     }
627
628     vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler));
629     if (!vblank_handler)
630     {
631         TDM_ERR("failed: alloc memory");
632         pthread_mutex_unlock(&private_display->lock);
633         return TDM_ERROR_OUT_OF_MEMORY;
634     }
635
636     LIST_ADD(&vblank_handler->link, &private_output->vblank_handler_list);
637     vblank_handler->private_output = private_output;
638     vblank_handler->func = func;
639     vblank_handler->user_data = user_data;
640
641     ret = func_display->output_wait_vblank(private_output->output_backend, interval,
642                                            sync, vblank_handler);
643     if (ret != TDM_ERROR_NONE)
644     {
645         pthread_mutex_unlock(&private_display->lock);
646         return ret;
647     }
648
649     if (!private_output->regist_vblank_cb)
650     {
651         private_output->regist_vblank_cb = 1;
652         ret = func_display->output_set_vblank_handler(private_output->output_backend,
653                                                       _tdm_output_cb_vblank);
654     }
655
656     pthread_mutex_unlock(&private_display->lock);
657
658     return ret;
659 }
660
661 EXTERN tdm_error
662 tdm_output_commit(tdm_output *output, int sync, tdm_output_commit_handler func, void *user_data)
663 {
664     tdm_func_display *func_display;
665     tdm_private_commit_handler *commit_handler;
666     OUTPUT_FUNC_ENTRY();
667
668     pthread_mutex_lock(&private_display->lock);
669
670     func_display = &private_display->func_display;
671
672     if (!func_display->output_commit)
673     {
674         pthread_mutex_unlock(&private_display->lock);
675         return TDM_ERROR_NONE;
676     }
677
678     commit_handler = calloc(1, sizeof(tdm_private_commit_handler));
679     if (!commit_handler)
680     {
681         TDM_ERR("failed: alloc memory");
682         pthread_mutex_unlock(&private_display->lock);
683         return TDM_ERROR_OUT_OF_MEMORY;
684     }
685
686     LIST_ADD(&commit_handler->link, &private_output->commit_handler_list);
687     commit_handler->private_output = private_output;
688     commit_handler->func = func;
689     commit_handler->user_data = user_data;
690
691     ret = func_display->output_commit(private_output->output_backend, sync, commit_handler);
692     if (ret != TDM_ERROR_NONE)
693     {
694         pthread_mutex_unlock(&private_display->lock);
695         return ret;
696     }
697
698     if (!private_output->regist_commit_cb)
699     {
700         private_output->regist_commit_cb = 1;
701         ret = func_display->output_set_commit_handler(private_output->output_backend,
702                                                       _tdm_output_cb_commit);
703     }
704
705     pthread_mutex_unlock(&private_display->lock);
706
707     return ret;
708 }
709
710 EXTERN tdm_error
711 tdm_output_set_mode(tdm_output *output, tdm_output_mode *mode)
712 {
713     tdm_func_display *func_display;
714     OUTPUT_FUNC_ENTRY();
715
716     TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
717
718     pthread_mutex_lock(&private_display->lock);
719
720     func_display = &private_display->func_display;
721
722     if (!func_display->output_set_mode)
723     {
724         pthread_mutex_unlock(&private_display->lock);
725         return TDM_ERROR_NONE;
726     }
727
728     ret = func_display->output_set_mode(private_output->output_backend, mode);
729
730     pthread_mutex_unlock(&private_display->lock);
731
732     return ret;
733 }
734
735 EXTERN tdm_error
736 tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
737 {
738     tdm_func_display *func_display;
739     OUTPUT_FUNC_ENTRY();
740
741     TDM_RETURN_VAL_IF_FAIL(mode != NULL, TDM_ERROR_INVALID_PARAMETER);
742
743     pthread_mutex_lock(&private_display->lock);
744
745     func_display = &private_display->func_display;
746
747     if (!func_display->output_get_mode)
748     {
749         pthread_mutex_unlock(&private_display->lock);
750         return TDM_ERROR_NONE;
751     }
752
753     ret = func_display->output_get_mode(private_output->output_backend, mode);
754
755     pthread_mutex_unlock(&private_display->lock);
756
757     return ret;
758 }
759
760 EXTERN tdm_error
761 tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value)
762 {
763     tdm_func_display *func_display;
764     OUTPUT_FUNC_ENTRY();
765
766     TDM_RETURN_VAL_IF_FAIL(dpms_value >= TDM_OUTPUT_DPMS_ON, TDM_ERROR_INVALID_PARAMETER);
767     TDM_RETURN_VAL_IF_FAIL(dpms_value < TDM_OUTPUT_DPMS_MAX, TDM_ERROR_INVALID_PARAMETER);
768
769     pthread_mutex_lock(&private_display->lock);
770
771     func_display = &private_display->func_display;
772
773     if (!func_display->output_set_dpms)
774     {
775         pthread_mutex_unlock(&private_display->lock);
776         return TDM_ERROR_NONE;
777     }
778
779     ret = func_display->output_set_dpms(private_output->output_backend, dpms_value);
780
781     pthread_mutex_unlock(&private_display->lock);
782
783     return ret;
784 }
785
786 EXTERN tdm_error
787 tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value)
788 {
789     tdm_func_display *func_display;
790     OUTPUT_FUNC_ENTRY();
791
792     TDM_RETURN_VAL_IF_FAIL(dpms_value != NULL, TDM_ERROR_INVALID_PARAMETER);
793
794     pthread_mutex_lock(&private_display->lock);
795
796     func_display = &private_display->func_display;
797
798     if (!func_display->output_get_dpms)
799     {
800         pthread_mutex_unlock(&private_display->lock);
801         return TDM_ERROR_NONE;
802     }
803
804     ret = func_display->output_get_dpms(private_output->output_backend, dpms_value);
805
806     pthread_mutex_unlock(&private_display->lock);
807
808     return ret;
809 }
810
811 EXTERN tdm_capture*
812 tdm_output_create_capture(tdm_output *output, tdm_error *error)
813 {
814     tdm_capture *capture = NULL;
815
816     OUTPUT_FUNC_ENTRY_ERROR();
817
818     pthread_mutex_lock(&private_display->lock);
819
820     capture = (tdm_capture*)tdm_capture_create_output_internal(private_output, error);
821
822     pthread_mutex_unlock(&private_display->lock);
823
824     return capture;
825 }
826
827 EXTERN tdm_error
828 tdm_layer_get_capabilities(tdm_layer *layer, tdm_layer_capability *capabilities)
829 {
830     LAYER_FUNC_ENTRY();
831
832     TDM_RETURN_VAL_IF_FAIL(capabilities != NULL, TDM_ERROR_INVALID_PARAMETER);
833
834     pthread_mutex_lock(&private_display->lock);
835
836     *capabilities = private_layer->caps.capabilities;
837
838     pthread_mutex_unlock(&private_display->lock);
839
840     return ret;
841 }
842
843 EXTERN tdm_error
844 tdm_layer_get_available_formats(tdm_layer *layer, const tbm_format **formats, int *count)
845 {
846     LAYER_FUNC_ENTRY();
847
848     TDM_RETURN_VAL_IF_FAIL(formats != 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     *formats = (const tbm_format*)private_layer->caps.formats;
854     *count = private_layer->caps.format_count;
855
856     pthread_mutex_unlock(&private_display->lock);
857
858     return ret;
859 }
860
861 EXTERN tdm_error
862 tdm_layer_get_available_properties(tdm_layer *layer, const tdm_prop **props, int *count)
863 {
864     LAYER_FUNC_ENTRY();
865
866     TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER);
867     TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER);
868
869     pthread_mutex_lock(&private_display->lock);
870
871     *props = (const tdm_prop*)private_layer->caps.props;
872     *count = private_layer->caps.prop_count;
873
874     pthread_mutex_unlock(&private_display->lock);
875
876     return ret;
877 }
878
879 EXTERN tdm_error
880 tdm_layer_get_zpos(tdm_layer *layer, unsigned int *zpos)
881 {
882     LAYER_FUNC_ENTRY();
883
884     TDM_RETURN_VAL_IF_FAIL(zpos != NULL, TDM_ERROR_INVALID_PARAMETER);
885
886     pthread_mutex_lock(&private_display->lock);
887
888     *zpos = private_layer->caps.zpos;
889
890     pthread_mutex_unlock(&private_display->lock);
891
892     return ret;
893 }
894
895 EXTERN tdm_error
896 tdm_layer_set_property(tdm_layer *layer, unsigned int id, tdm_value value)
897 {
898     tdm_func_display *func_display;
899     LAYER_FUNC_ENTRY();
900
901     pthread_mutex_lock(&private_display->lock);
902
903     func_display = &private_display->func_display;
904
905     if (!func_display->layer_set_property)
906     {
907         pthread_mutex_unlock(&private_display->lock);
908         return TDM_ERROR_NONE;
909     }
910
911     ret = func_display->layer_set_property(private_layer->layer_backend, id, value);
912
913     pthread_mutex_unlock(&private_display->lock);
914
915     return ret;
916 }
917
918 EXTERN tdm_error
919 tdm_layer_get_property(tdm_layer *layer, unsigned int id, tdm_value *value)
920 {
921     tdm_func_display *func_display;
922     LAYER_FUNC_ENTRY();
923
924     TDM_RETURN_VAL_IF_FAIL(value != NULL, TDM_ERROR_INVALID_PARAMETER);
925
926     pthread_mutex_lock(&private_display->lock);
927
928     func_display = &private_display->func_display;
929
930     if (!func_display->layer_get_property)
931     {
932         pthread_mutex_unlock(&private_display->lock);
933         return TDM_ERROR_NONE;
934     }
935
936     ret = func_display->layer_get_property(private_layer->layer_backend, id, value);
937
938     pthread_mutex_unlock(&private_display->lock);
939
940     return ret;
941 }
942
943 EXTERN tdm_error
944 tdm_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
945 {
946     tdm_func_display *func_display;
947     LAYER_FUNC_ENTRY();
948
949     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
950
951     pthread_mutex_lock(&private_display->lock);
952
953     func_display = &private_display->func_display;
954
955     private_layer->usable = 0;
956
957     if (!func_display->layer_set_info)
958     {
959         pthread_mutex_unlock(&private_display->lock);
960         return TDM_ERROR_NONE;
961     }
962
963     ret = func_display->layer_set_info(private_layer->layer_backend, info);
964
965     pthread_mutex_unlock(&private_display->lock);
966
967     return ret;
968 }
969
970 EXTERN tdm_error
971 tdm_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
972 {
973     tdm_func_display *func_display;
974     LAYER_FUNC_ENTRY();
975
976     TDM_RETURN_VAL_IF_FAIL(info != NULL, TDM_ERROR_INVALID_PARAMETER);
977
978     pthread_mutex_lock(&private_display->lock);
979
980     func_display = &private_display->func_display;
981
982     if (!func_display->layer_get_info)
983     {
984         pthread_mutex_unlock(&private_display->lock);
985         return TDM_ERROR_NONE;
986     }
987
988     ret = func_display->layer_get_info(private_layer->layer_backend, info);
989
990     pthread_mutex_unlock(&private_display->lock);
991
992     return ret;
993 }
994
995 EXTERN tdm_error
996 tdm_layer_set_buffer(tdm_layer *layer, tdm_buffer *buffer)
997 {
998     tdm_func_display *func_display;
999     LAYER_FUNC_ENTRY();
1000
1001     TDM_RETURN_VAL_IF_FAIL(buffer != NULL, TDM_ERROR_INVALID_PARAMETER);
1002
1003     pthread_mutex_lock(&private_display->lock);
1004
1005     func_display = &private_display->func_display;
1006
1007     private_layer->usable = 0;
1008
1009     if (!func_display->layer_set_buffer)
1010     {
1011         pthread_mutex_unlock(&private_display->lock);
1012         return TDM_ERROR_NONE;
1013     }
1014
1015     if (private_layer->current_buffer)
1016     {
1017         /* TODO: need to unref after next buffer is showing on screen */
1018         tdm_buffer_unref_backend(private_layer->current_buffer);
1019         tdm_buffer_unref(private_layer->current_buffer);
1020     }
1021
1022     private_layer->current_buffer = tdm_buffer_ref(buffer, NULL);
1023     tdm_buffer_ref_backend(buffer);
1024
1025     ret = func_display->layer_set_buffer(private_layer->layer_backend,
1026                                          tdm_buffer_get_surface(buffer));
1027
1028     pthread_mutex_unlock(&private_display->lock);
1029
1030     return ret;
1031 }
1032
1033 EXTERN tdm_error
1034 tdm_layer_unset_buffer(tdm_layer *layer)
1035 {
1036     tdm_func_display *func_display;
1037     LAYER_FUNC_ENTRY();
1038
1039     pthread_mutex_lock(&private_display->lock);
1040
1041     func_display = &private_display->func_display;
1042
1043     if (private_layer->current_buffer)
1044     {
1045         tdm_buffer_unref(private_layer->current_buffer);
1046         tdm_buffer_unref_backend(private_layer->current_buffer);
1047         private_layer->current_buffer = NULL;
1048     }
1049
1050     private_layer->usable = 1;
1051
1052     if (!func_display->layer_unset_buffer)
1053     {
1054         pthread_mutex_unlock(&private_display->lock);
1055         return TDM_ERROR_NONE;
1056     }
1057
1058     ret = func_display->layer_unset_buffer(private_layer->layer_backend);
1059
1060     pthread_mutex_unlock(&private_display->lock);
1061
1062     return ret;
1063 }
1064
1065 EXTERN tdm_error
1066 tdm_layer_is_usable(tdm_layer *layer, unsigned int *usable)
1067 {
1068     LAYER_FUNC_ENTRY();
1069
1070     TDM_RETURN_VAL_IF_FAIL(usable != NULL, TDM_ERROR_INVALID_PARAMETER);
1071
1072     pthread_mutex_lock(&private_display->lock);
1073
1074     *usable = private_layer->usable;
1075
1076     pthread_mutex_unlock(&private_display->lock);
1077
1078     return ret;
1079 }
1080
1081
1082 EXTERN tdm_capture*
1083 tdm_layer_create_capture(tdm_layer *layer, tdm_error *error)
1084 {
1085     tdm_capture *capture = NULL;
1086
1087     LAYER_FUNC_ENTRY_ERROR();
1088
1089     pthread_mutex_lock(&private_display->lock);
1090
1091     capture = (tdm_capture*)tdm_capture_create_layer_internal(private_layer, error);
1092
1093     pthread_mutex_unlock(&private_display->lock);
1094
1095     return capture;
1096 }