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 <dynamicbox_errno.h> /* For error code */
32 #include <dynamicbox_buffer.h>
55 int fb_init(void *disp)
65 static inline void update_fb_size(struct fb_info *info)
67 info->bufsz = info->w * info->h * info->pixels;
70 static inline int sync_for_file(struct fb_info *info)
73 struct buffer *buffer;
75 buffer = info->buffer;
77 if (!buffer) { /* Ignore this sync request */
78 return DBOX_STATUS_ERROR_NONE;
81 if (buffer->state != CREATED) {
82 ErrPrint("Invalid state of a FB\n");
83 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
86 if (buffer->type != DBOX_BUFFER_TYPE_FILE) {
87 ErrPrint("Invalid buffer\n");
88 return DBOX_STATUS_ERROR_NONE;
91 fd = open(util_uri_to_path(info->id), O_RDONLY);
93 ErrPrint("Failed to open a file (%s) because of (%s)\n",
94 util_uri_to_path(info->id), strerror(errno));
98 * But return ZERO, even if we couldn't get a buffer file,
99 * the viewer can draw empty screen.
101 * and then update it after it gots update events
103 return DBOX_STATUS_ERROR_NONE;
106 if (read(fd, buffer->data, info->bufsz) != info->bufsz) {
107 ErrPrint("read: %s\n", strerror(errno));
109 ErrPrint("close: %s\n", strerror(errno));
114 * But return ZERO, even if we couldn't get a buffer file,
115 * the viewer can draw empty screen.
117 * and then update it after it gots update events
119 return DBOX_STATUS_ERROR_NONE;
123 ErrPrint("close: %s\n", strerror(errno));
125 return DBOX_STATUS_ERROR_NONE;
128 int fb_sync(struct fb_info *info, int x, int y, int w, int h)
131 ErrPrint("FB Handle is not valid\n");
132 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
135 if (!info->id || info->id[0] == '\0') {
136 DbgPrint("Ingore sync\n");
137 return DBOX_STATUS_ERROR_NONE;
140 if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
141 return sync_for_file(info);
142 } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
143 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
144 /* No need to do sync */
145 return DBOX_STATUS_ERROR_NONE;
148 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
151 struct fb_info *fb_create(const char *id, int w, int h)
153 struct fb_info *info;
155 if (!id || id[0] == '\0') {
156 ErrPrint("Invalid ID\n");
160 info = calloc(1, sizeof(*info));
162 ErrPrint("Heap: %s\n", strerror(errno));
166 info->id = strdup(id);
168 ErrPrint("Heap: %s\n", strerror(errno));
173 info->pixels = sizeof(int); /* Use the default pixels(depth) */
175 if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) {
176 DbgPrint("SHMID: %d is gotten\n", info->handle);
177 } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) {
178 DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels);
179 ErrPrint("Unsupported\n");
183 info->handle = DBOX_STATUS_ERROR_INVALID_PARAMETER;
194 int fb_destroy(struct fb_info *info)
197 ErrPrint("Handle is not valid\n");
198 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
202 struct buffer *buffer;
203 buffer = info->buffer;
210 return DBOX_STATUS_ERROR_NONE;
213 int fb_is_created(struct fb_info *info)
216 ErrPrint("Handle is not valid\n");
220 if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) {
222 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) {
226 path = util_uri_to_path(info->id);
227 if (path && access(path, F_OK | R_OK) == 0) {
230 ErrPrint("access: %s (%s)\n", strerror(errno), path);
237 void *fb_acquire_buffer(struct fb_info *info)
239 struct buffer *buffer;
242 ErrPrint("info == NIL\n");
243 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
248 if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
249 ErrPrint("Unsupported Type\n");
250 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
252 } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
253 update_fb_size(info);
255 buffer = calloc(1, sizeof(*buffer) + info->bufsz);
257 ErrPrint("Heap: %s\n", strerror(errno));
259 dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY);
263 buffer->type = DBOX_BUFFER_TYPE_FILE;
265 buffer->state = CREATED;
267 info->buffer = buffer;
270 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
271 buffer = shmat(info->handle, NULL, 0);
272 if (buffer == (void *)-1) {
273 ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle);
274 dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT);
280 ErrPrint("Buffer is not created (%s)\n", info->id);
281 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
286 buffer = info->buffer;
288 switch (buffer->type) {
289 case DBOX_BUFFER_TYPE_FILE:
292 case DBOX_BUFFER_TYPE_PIXMAP:
294 DbgPrint("Unknwon FP: %d\n", buffer->type);
295 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
302 int fb_release_buffer(void *data)
304 struct buffer *buffer;
307 ErrPrint("buffer data == NIL\n");
308 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
309 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
312 buffer = container_of(data, struct buffer, data);
314 if (buffer->state != CREATED) {
315 ErrPrint("Invalid handle\n");
316 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
317 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
320 switch (buffer->type) {
321 case DBOX_BUFFER_TYPE_SHM:
322 if (shmdt(buffer) < 0) {
323 ErrPrint("shmdt: %s\n", strerror(errno));
326 case DBOX_BUFFER_TYPE_FILE:
328 if (buffer->refcnt == 0) {
329 struct fb_info *info;
332 buffer->state = DBOX_FB_STATE_DESTROYED;
335 if (info && info->buffer == buffer) {
340 case DBOX_BUFFER_TYPE_PIXMAP:
342 ErrPrint("Unknwon buffer type\n");
343 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
347 return DBOX_STATUS_ERROR_NONE;
350 int fb_refcnt(void *data)
352 struct buffer *buffer;
357 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
358 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
361 buffer = container_of(data, struct buffer, data);
363 if (buffer->state != CREATED) {
364 ErrPrint("Invalid handle\n");
365 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
366 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
369 switch (buffer->type) {
370 case DBOX_BUFFER_TYPE_SHM:
371 if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) {
372 ErrPrint("Error: %s\n", strerror(errno));
373 dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT);
374 return DBOX_STATUS_ERROR_FAULT;
377 ret = buf.shm_nattch;
379 case DBOX_BUFFER_TYPE_FILE:
380 ret = buffer->refcnt;
382 case DBOX_BUFFER_TYPE_PIXMAP:
384 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
385 ret = DBOX_STATUS_ERROR_INVALID_PARAMETER;
392 const char *fb_id(struct fb_info *info)
394 return info ? info->id : NULL;
397 int fb_get_size(struct fb_info *info, int *w, int *h)
400 ErrPrint("Handle is not valid\n");
401 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
406 return DBOX_STATUS_ERROR_NONE;
409 int fb_size(struct fb_info *info)
412 dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER);
416 update_fb_size(info);
421 int fb_type(struct fb_info *info)
423 struct buffer *buffer;
426 return DBOX_BUFFER_TYPE_ERROR;
429 buffer = info->buffer;
431 int type = DBOX_BUFFER_TYPE_ERROR;
434 * Try to get this from SCHEMA
437 if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) {
438 type = DBOX_BUFFER_TYPE_FILE;
439 } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
440 /* Unsupported type */
441 } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
442 type = DBOX_BUFFER_TYPE_SHM;