• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 Advanced Driver Information Technology Joint Venture GmbH
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <sys/stat.h>
28 #include <sys/time.h>
29 #include <pthread.h>
30 #include <getopt.h>
31 
32 #include "ilm_control.h"
33 
34 t_ilm_uint screenWidth;
35 t_ilm_uint screenHeight;
36 static t_ilm_uint layer = 0;
37 pthread_mutex_t mutex;
38 static pthread_cond_t  waiterVariable = PTHREAD_COND_INITIALIZER;
39 static int number_of_surfaces = 0;
40 char display_name[256] = {0};
41 
configure_ilm_surface(t_ilm_uint id,t_ilm_uint width,t_ilm_uint height)42 static void configure_ilm_surface(t_ilm_uint id, t_ilm_uint width, t_ilm_uint height)
43 {
44     ilm_surfaceSetDestinationRectangle(id, 0, 0, width, height);
45     ilm_surfaceSetSourceRectangle(id, 0, 0, width, height);
46     ilm_surfaceSetVisibility(id, ILM_TRUE);
47     ilm_layerAddSurface(layer,id);
48     ilm_surfaceRemoveNotification(id);
49 
50     ilm_commitChanges();
51     pthread_cond_signal( &waiterVariable );
52 
53     printf("layer-add-surfaces: surface (%u) configured with:\n"
54            "    dst region: x:0 y:0 w:%u h:%u\n"
55            "    src region: x:0 y:0 w:%u h:%u\n"
56            "    visibility: TRUE\n"
57            "    added to layer (%u)\n", id, width, height, width, height,layer);
58 }
59 
surfaceCallbackFunction(t_ilm_uint id,struct ilmSurfaceProperties * sp,t_ilm_notification_mask m)60 static void surfaceCallbackFunction(t_ilm_uint id, struct ilmSurfaceProperties* sp, t_ilm_notification_mask m)
61 {
62     if ((unsigned)m & ILM_NOTIFICATION_CONFIGURED)
63     {
64         configure_ilm_surface(id, sp->origSourceWidth, sp->origSourceHeight);
65     }
66 }
67 
callbackFunction(ilmObjectType object,t_ilm_uint id,t_ilm_bool created,void * user_data)68 static void callbackFunction(ilmObjectType object, t_ilm_uint id, t_ilm_bool created, void *user_data)
69 {
70     (void)user_data;
71     struct ilmSurfaceProperties sp;
72 
73     if (object == ILM_SURFACE) {
74         if (created) {
75             if (number_of_surfaces > 0) {
76                 number_of_surfaces--;
77                 printf("layer-add-surfaces: surface (%d) created\n",id);
78                 // always get configured event to follow the surface changings
79                 ilm_surfaceAddNotification(id,&surfaceCallbackFunction);
80                 ilm_commitChanges();
81                 ilm_getPropertiesOfSurface(id, &sp);
82 
83                 if ((sp.origSourceWidth != 0) && (sp.origSourceHeight !=0))
84                 {   // surface is already configured
85                     configure_ilm_surface(id, sp.origSourceWidth, sp.origSourceHeight);
86                 }
87             }
88         }
89         else if(!created)
90             printf("layer-add-surfaces: surface (%u) destroyed\n",id);
91     } else if (object == ILM_LAYER) {
92         if (created)
93             printf("layer-add-surfaces: layer (%u) created\n",id);
94         else if(!created)
95             printf("layer-add-surfaces: layer (%u) destroyed\n",id);
96     }
97 }
98 
shutdownCallbackFunction(t_ilm_shutdown_error_type error_type,int errornum,void * user_data)99 static void shutdownCallbackFunction(t_ilm_shutdown_error_type error_type,
100                                      int errornum,
101                                      void *user_data)
102 {
103     (void) user_data;
104 
105     switch (error_type) {
106         case ILM_ERROR_WAYLAND:
107         {
108             printf("layer-add-surfaces: exit, ilm shutdown due to wayland error: %s\n",
109                    strerror(errornum));
110             break;
111         }
112         case ILM_ERROR_POLL:
113         {
114             printf("layer-add-surfaces: exit, ilm shutdown due to poll error: %s\n",
115                    strerror(errornum));
116             break;
117         }
118         default:
119         {
120             printf("layer-add-surfaces: exit, ilm shutdown due to unknown reason: %s\n",
121                    strerror(errornum));
122         }
123     }
124 
125     exit(1);
126 }
127 
128 /* Choose the display with the largest resolution.*/
choose_screen(void)129 static t_ilm_uint choose_screen(void)
130 {
131     struct ilmScreenProperties screenProperties;
132     t_ilm_uint* screen_IDs = NULL;
133     t_ilm_uint screen_ID = 0;
134     t_ilm_uint screen_count = 0;
135     t_ilm_uint choosen_width = 0;
136     t_ilm_uint choosen_height = 0;
137     t_ilm_uint i;
138 
139     ilm_getScreenIDs(&screen_count, &screen_IDs);
140 
141     for (i = 0; i<screen_count; i++)
142     {
143         ilm_getPropertiesOfScreen(screen_IDs[i], &screenProperties);
144         if (!strcmp(screenProperties.connectorName, display_name)) {
145             choosen_width = screenProperties.screenWidth;
146             choosen_height = screenProperties.screenHeight;
147             screen_ID = screen_IDs[i];
148             break;
149         }
150         else if (screenProperties.screenWidth > choosen_width) {
151             choosen_width = screenProperties.screenWidth;
152             choosen_height = screenProperties.screenHeight;
153             screen_ID = screen_IDs[i];
154         }
155     }
156 
157     screenWidth = choosen_width;
158     screenHeight = choosen_height;
159 
160     free(screen_IDs);
161 
162     return screen_ID;
163 }
164 
165 static int
usage(int ret)166 usage(int ret)
167 {
168     fprintf(stderr, "    -h,  --help                  display this help and exit.\n"
169                     "    -d,  --display-name          name of the display which will be used,\n"
170                     "                                 e.g.: HDMI-A-1, LVDS1\n"
171                     "                                 If it is not set, display with highest resolution is used.\n"
172                     "    -l,  --layer-id              id of the used ILM layer. It has to be set\n"
173                     "    -s,  --surface-count         number of surfaces which will be added to\n"
174                     "                                 the layer. It has to be set\n");
175     exit(ret);
176 }
177 
parse_options(int argc,char * argv[])178 void parse_options(int argc, char *argv[])
179 {
180     int opt;
181     static const struct option options[] = {
182         { "help",              no_argument, NULL, 'h' },
183         { "layer-id",              required_argument, 0, 'l' },
184         { "surface-count",           required_argument, 0, 's' },
185         { "display-name", required_argument, NULL, 'd' },
186         { 0,                   0,           NULL, 0 }
187     };
188 
189     while (1) {
190         opt = getopt_long(argc, argv, "hl:s:d:", options, NULL);
191 
192         if (opt == -1)
193             break;
194 
195         switch (opt) {
196             case 'h':
197                 usage(0);
198                 break;
199             case 'l':
200                 layer = atoi(optarg);
201                 break;
202             case 's':
203                 number_of_surfaces = atoi(optarg);
204                 break;
205             case 'd':
206                 strcpy(display_name, optarg);
207                 break;
208             default:
209                 usage(-1);
210                 break;
211         }
212     }
213 
214     printf("layer-add-surfaces: layer (%u) on display (%s) created, waiting for %d surfaces ...\n",
215                layer,
216                display_name,
217                number_of_surfaces);
218 }
219 
main(int argc,char * argv[])220 int main (int argc, char *argv[])
221 {
222     // Get command-line options
223     if ( argc < 3) {
224         usage(-1);
225     }
226 
227     // Check the first character of the first parameter
228     if (!strncmp(argv[1], "-", 1)) {
229         parse_options(argc, argv);
230     } else {
231         layer = strtol(argv[1], NULL, 0);
232         number_of_surfaces = strtol(argv[2], NULL, 0);
233     }
234 
235     if (!number_of_surfaces || !layer)
236         usage(-1);
237 
238     pthread_mutexattr_t a;
239     if (pthread_mutexattr_init(&a) != 0)
240     {
241        return -1;
242     }
243 
244     if (pthread_mutexattr_settype(&a, PTHREAD_MUTEX_RECURSIVE) != 0)
245     {
246        pthread_mutexattr_destroy(&a);
247        return -1;
248     }
249 
250     if (pthread_mutex_init(&mutex, &a) != 0)
251     {
252         pthread_mutexattr_destroy(&a);
253         fprintf(stderr, "layer-add-surfaces: failed to initialize pthread_mutex\n");
254         return -1;
255     }
256 
257     pthread_mutexattr_destroy(&a);
258 
259     t_ilm_layer renderOrder[1];
260     t_ilm_uint screen_ID;
261     renderOrder[0] = layer;
262     if (ilm_init() == ILM_FAILED) {
263         fprintf(stderr, "layer-add-surfaces: ilm_init failed\n");
264         return -1;
265     }
266 
267     ilm_registerShutdownNotification(shutdownCallbackFunction, NULL);
268 
269     screen_ID = choose_screen();
270     ilm_layerCreateWithDimension(&layer, screenWidth, screenHeight);
271     printf("layer-add-surfaces: layer (%d) destination region: x:0 y:0 w:%u h:%u\n", layer, screenWidth, screenHeight);
272     ilm_layerSetVisibility(layer,ILM_TRUE);
273     printf("layer-add-surfaces: layer (%d) visibility TRUE\n", layer);
274     ilm_displaySetRenderOrder(screen_ID, renderOrder, 1);
275     ilm_commitChanges();
276     ilm_registerNotification(callbackFunction, NULL);
277 
278     while (number_of_surfaces > 0) {
279         pthread_mutex_lock(&mutex);
280         pthread_cond_wait( &waiterVariable, &mutex);
281     }
282 
283     ilm_unregisterNotification();
284     ilm_destroy();
285 
286     return 0;
287 }
288