2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <sys/types.h>
31 #include <livebox-errno.h> /* For error code */
50 struct buffer { /*!< Must has to be sync with slave & provider */
53 DESTROYED = 0x00dead00
55 enum buffer_type type;
65 int fb_init(void *disp)
75 static inline void update_fb_size(struct fb_info *info)
77 info->bufsz = info->w * info->h * info->pixels;
80 static inline int sync_for_file(struct fb_info *info)
83 struct buffer *buffer;
85 buffer = info->buffer;
87 if (!buffer) { /* Ignore this sync request */
88 return LB_STATUS_SUCCESS;
91 if (buffer->state != CREATED) {
92 ErrPrint("Invalid state of a FB\n");
93 return LB_STATUS_ERROR_INVALID;
96 if (buffer->type != BUFFER_TYPE_FILE) {
97 ErrPrint("Invalid buffer\n");
98 return LB_STATUS_SUCCESS;
101 fd = open(util_uri_to_path(info->id), O_RDONLY);
103 ErrPrint("Failed to open a file (%s) because of (%s)\n",
104 util_uri_to_path(info->id), strerror(errno));
108 * But return ZERO, even if we couldn't get a buffer file,
109 * the viewer can draw empty screen.
111 * and then update it after it gots update events
113 return LB_STATUS_SUCCESS;
116 if (read(fd, buffer->data, info->bufsz) != info->bufsz) {
117 ErrPrint("read: %s\n", strerror(errno));
119 ErrPrint("close: %s\n", strerror(errno));
124 * But return ZERO, even if we couldn't get a buffer file,
125 * the viewer can draw empty screen.
127 * and then update it after it gots update events
129 return LB_STATUS_SUCCESS;
133 ErrPrint("close: %s\n", strerror(errno));
135 return LB_STATUS_SUCCESS;
138 int fb_sync(struct fb_info *info)
141 ErrPrint("FB Handle is not valid\n");
142 return LB_STATUS_ERROR_INVALID;
145 if (!info->id || info->id[0] == '\0') {
146 DbgPrint("Ingore sync\n");
147 return LB_STATUS_SUCCESS;
150 if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
151 return sync_for_file(info);
152 } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
153 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
154 /* No need to do sync */
155 return LB_STATUS_SUCCESS;
158 return LB_STATUS_ERROR_INVALID;
161 struct fb_info *fb_create(const char *id, int w, int h)
163 struct fb_info *info;
165 if (!id || id[0] == '\0') {
166 ErrPrint("Invalid ID\n");
170 info = calloc(1, sizeof(*info));
172 ErrPrint("Heap: %s\n", strerror(errno));
176 info->id = strdup(id);
178 ErrPrint("Heap: %s\n", strerror(errno));
183 info->pixels = sizeof(int); /* Use the default pixels(depth) */
185 if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) {
186 DbgPrint("SHMID: %d is gotten\n", info->handle);
187 } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) {
188 DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels);
189 ErrPrint("Unsupported\n");
193 info->handle = LB_STATUS_ERROR_INVALID;
204 int fb_destroy(struct fb_info *info)
207 ErrPrint("Handle is not valid\n");
208 return LB_STATUS_ERROR_INVALID;
212 struct buffer *buffer;
213 buffer = info->buffer;
220 return LB_STATUS_SUCCESS;
223 int fb_is_created(struct fb_info *info)
226 ErrPrint("Handle is not valid\n");
230 if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) {
232 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) {
236 path = util_uri_to_path(info->id);
237 if (path && access(path, F_OK | R_OK) == 0) {
240 ErrPrint("access: %s (%s)\n", strerror(errno), path);
247 void *fb_acquire_buffer(struct fb_info *info)
249 struct buffer *buffer;
252 ErrPrint("info == NIL\n");
257 if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
258 ErrPrint("Unsupported Type\n");
260 } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
261 update_fb_size(info);
263 buffer = calloc(1, sizeof(*buffer) + info->bufsz);
265 ErrPrint("Heap: %s\n", strerror(errno));
270 buffer->type = BUFFER_TYPE_FILE;
272 buffer->state = CREATED;
274 info->buffer = buffer;
277 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
278 buffer = shmat(info->handle, NULL, 0);
279 if (buffer == (void *)-1) {
280 ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle);
286 ErrPrint("Buffer is not created (%s)\n", info->id);
291 buffer = info->buffer;
293 switch (buffer->type) {
294 case BUFFER_TYPE_FILE:
297 case BUFFER_TYPE_PIXMAP:
299 DbgPrint("Unknwon FP: %d\n", buffer->type);
306 int fb_release_buffer(void *data)
308 struct buffer *buffer;
311 ErrPrint("buffer data == NIL\n");
312 return LB_STATUS_ERROR_INVALID;
315 buffer = container_of(data, struct buffer, data);
317 if (buffer->state != CREATED) {
318 ErrPrint("Invalid handle\n");
319 return LB_STATUS_ERROR_INVALID;
322 switch (buffer->type) {
323 case BUFFER_TYPE_SHM:
324 if (shmdt(buffer) < 0) {
325 ErrPrint("shmdt: %s\n", strerror(errno));
328 case BUFFER_TYPE_FILE:
330 if (buffer->refcnt == 0) {
331 struct fb_info *info;
334 buffer->state = DESTROYED;
337 if (info && info->buffer == buffer) {
342 case BUFFER_TYPE_PIXMAP:
344 ErrPrint("Unknwon buffer type\n");
348 return LB_STATUS_SUCCESS;
351 int fb_refcnt(void *data)
353 struct buffer *buffer;
358 return LB_STATUS_ERROR_INVALID;
361 buffer = container_of(data, struct buffer, data);
363 if (buffer->state != CREATED) {
364 ErrPrint("Invalid handle\n");
365 return LB_STATUS_ERROR_INVALID;
368 switch (buffer->type) {
369 case BUFFER_TYPE_SHM:
370 if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) {
371 ErrPrint("Error: %s\n", strerror(errno));
372 return LB_STATUS_ERROR_FAULT;
375 ret = buf.shm_nattch;
377 case BUFFER_TYPE_FILE:
378 ret = buffer->refcnt;
380 case BUFFER_TYPE_PIXMAP:
382 ret = LB_STATUS_ERROR_INVALID;
389 const char *fb_id(struct fb_info *info)
391 return info ? info->id : NULL;
394 int fb_get_size(struct fb_info *info, int *w, int *h)
397 ErrPrint("Handle is not valid\n");
398 return LB_STATUS_ERROR_INVALID;
403 return LB_STATUS_SUCCESS;
406 int fb_size(struct fb_info *info)
412 update_fb_size(info);
417 int fb_type(struct fb_info *info)
419 struct buffer *buffer;
422 return BUFFER_TYPE_ERROR;
425 buffer = info->buffer;
427 int type = BUFFER_TYPE_ERROR;
430 * Try to get this from SCHEMA
433 if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
434 type = BUFFER_TYPE_FILE;
435 } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
436 /* Unsupported type */
437 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
438 type = BUFFER_TYPE_SHM;