PP_Resource ppb_url_response_info_get_body_as_file_ref(PP_Resource response) { struct pp_url_response_info_s *ri = pp_resource_acquire(response,PP_RESOURCE_URL_RESPONSE_INFO); if (!ri) { trace_error("%s, bad resource\n", __func__); return 0; } struct pp_url_loader_s *ul = ri->url_loader; PP_Resource file_ref = pp_resource_allocate(PP_RESOURCE_FILE_REF, ri->instance); struct pp_file_ref_s *fr = pp_resource_acquire(file_ref, PP_RESOURCE_FILE_REF); if (!fr) { trace_error("%s, resource allocation failure\n", __func__); pp_resource_release(response); return 0; } fr->fd = dup(ul->fd); fr->type = PP_FILE_REF_TYPE_FD; pp_resource_release(file_ref); pp_resource_release(response); return file_ref; }
PP_Resource ppb_url_loader_get_response_info(PP_Resource loader) { struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER); if (!ul) { trace_error("%s, bad resource\n", __func__); return 0; } PP_Resource response_info = pp_resource_allocate(PP_RESOURCE_URL_RESPONSE_INFO, ul->instance); struct pp_url_response_info_s *ri = pp_resource_acquire(response_info, PP_RESOURCE_URL_RESPONSE_INFO); if (!ri) { trace_error("%s, resource allocation failure\n", __func__); pp_resource_release(loader); return 0; } pp_resource_ref(loader); ri->url_loader_id = loader; ri->url_loader = ul; pp_resource_release(response_info); pp_resource_release(loader); return response_info; }
int32_t ppb_flash_message_loop_run(PP_Resource flash_message_loop) { struct pp_flash_message_loop_s *fml = pp_resource_acquire(flash_message_loop, PP_RESOURCE_FLASH_MESSAGE_LOOP); if (!fml) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } PP_Resource message_loop = ppb_message_loop_get_current(); fml->running = 1; fml->message_loop = message_loop; fml->depth = ppb_message_loop_get_depth(message_loop) + 1; pp_resource_ref(flash_message_loop); // prevent destroy of running loop pp_resource_release(flash_message_loop); // launching nested loop without depth increase to prevent hang up of previously pushed tasks ppb_message_loop_run_int(message_loop, ML_NESTED); fml = pp_resource_acquire(flash_message_loop, PP_RESOURCE_FLASH_MESSAGE_LOOP); if (fml) { fml->running = 0; pp_resource_release(flash_message_loop); } pp_resource_unref(flash_message_loop); return PP_OK; }
PP_Resource ppb_audio_get_current_config(PP_Resource audio) { struct pp_audio_s *a = pp_resource_acquire(audio, PP_RESOURCE_AUDIO); if (!a) { trace_error("%s, bad resource\n", __func__); return 0; } PP_Resource audio_config = pp_resource_allocate(PP_RESOURCE_AUDIO_CONFIG, a->instance); struct pp_audio_config_s *ac = pp_resource_acquire(audio_config, PP_RESOURCE_AUDIO_CONFIG); if (!ac) { trace_error("%s, resource allocation failure\n", __func__); audio_config = 0; goto err; } ac->sample_rate = a->sample_rate; ac->sample_frame_count = a->sample_frame_count; pp_resource_release(audio_config); err: pp_resource_release(audio); return audio_config; }
PP_Resource ppb_host_resolver_get_net_address_1_0(PP_Resource host_resolver, uint32_t index) { PP_Resource net_address = 0; struct pp_host_resolver_s *hr = pp_resource_acquire(host_resolver, PP_RESOURCE_HOST_RESOLVER); if (!hr) { trace_error("%s, bad resource\n", __func__); goto err_1; } if (index >= hr->addr_count) goto err_2; net_address = pp_resource_allocate(PP_RESOURCE_NET_ADDRESS, hr->instance); struct pp_net_address_s *na = pp_resource_acquire(net_address, PP_RESOURCE_NET_ADDRESS); if (!na) { trace_error("%s, resource allocation failed\n", __func__); goto err_2; } memcpy(&na->addr, &hr->addrs[index], sizeof(struct PP_NetAddress_Private)); pp_resource_release(net_address); err_2: pp_resource_release(host_resolver); err_1: return net_address; }
void ppb_video_decoder_assign_picture_buffers(PP_Resource video_decoder, uint32_t no_of_buffers, const struct PP_PictureBuffer_Dev buffers[]) { struct pp_video_decoder_s *vd = pp_resource_acquire(video_decoder, PP_RESOURCE_VIDEO_DECODER); if (!vd) { trace_error("%s, bad resource\n", __func__); goto err_1; } struct pp_graphics3d_s *g3d = pp_resource_acquire(vd->graphics3d, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, bad graphics3d context\n", __func__); goto err_2; } vd->buffers = malloc(no_of_buffers * sizeof(*vd->buffers)); if (!vd->buffers) { trace_error("%s, memory allocation failure\n", __func__); goto err_3; } vd->buffer_count = no_of_buffers; for (uintptr_t k = 0; k < no_of_buffers; k ++) { vd->buffers[k].id = buffers[k].id; vd->buffers[k].width = buffers[k].size.width; vd->buffers[k].height = buffers[k].size.height; vd->buffers[k].texture_id = buffers[k].texture_id; vd->buffers[k].used = 0; pthread_mutex_lock(&display.lock); vd->buffers[k].pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), buffers[k].size.width, buffers[k].size.height, g3d->depth); int tfp_pixmap_attrs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_MIPMAP_TEXTURE_EXT, GL_FALSE, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, GL_NONE }; vd->buffers[k].glx_pixmap = glXCreatePixmap(display.x, g3d->fb_config, vd->buffers[k].pixmap, tfp_pixmap_attrs); pthread_mutex_unlock(&display.lock); if (vd->buffers[k].glx_pixmap == None) { trace_error("%s, failed to create GLX pixmap\n", __func__); goto err_3; } } err_3: pp_resource_release(vd->graphics3d); err_2: pp_resource_release(video_decoder); err_1: ; }
PP_Bool ppb_browser_font_trusted_draw_text_at(PP_Resource font, PP_Resource image_data, const struct PP_BrowserFont_Trusted_TextRun *text, const struct PP_Point *position, uint32_t color, const struct PP_Rect *clip, PP_Bool image_data_is_opaque) { (void)image_data_is_opaque; // TODO: is it worth implementing? struct pp_browser_font_s *bf = pp_resource_acquire(font, PP_RESOURCE_BROWSER_FONT); if (!bf) return PP_FALSE; struct pp_image_data_s *id = pp_resource_acquire(image_data, PP_RESOURCE_IMAGE_DATA); if (!id) { pp_resource_release(font); return PP_FALSE; } cairo_t *cr = cairo_create(id->cairo_surf); if (clip) { cairo_rectangle(cr, clip->point.x, clip->point.y, clip->size.width, clip->size.height); cairo_clip(cr); } PangoFontMetrics *m = pango_font_get_metrics(bf->font, NULL); int32_t ascent = pango_font_metrics_get_ascent(m) / PANGO_SCALE; cairo_surface_mark_dirty(id->cairo_surf); if (position) cairo_move_to(cr, position->x, position->y - ascent); else cairo_move_to(cr, 0, 0); pango_font_metrics_unref(m); cairo_set_source_rgba(cr, ((color >> 16) & 0xffu) / 255.0, ((color >> 8) & 0xffu) / 255.0, ((color >> 0) & 0xffu) / 255.0, ((color >> 24) & 0xffu) / 255.0); PangoLayout *layout = pango_cairo_create_layout(cr); uint32_t len = 0; const char *s = ""; if (text->text.type == PP_VARTYPE_STRING) s = ppb_var_var_to_utf8(text->text, &len); // TODO: factor into rtl direction pango_layout_set_font_description(layout, bf->font_desc); pango_layout_set_text(layout, s, len); pango_cairo_layout_path(cr, layout); cairo_fill(cr); g_object_unref(layout); cairo_surface_flush(id->cairo_surf); cairo_destroy(cr); pp_resource_release(font); pp_resource_release(image_data); return PP_FALSE; }
static PP_Resource do_ppb_audio_create(PP_Instance instance, PP_Resource audio_config, PPB_Audio_Callback_1_0 audio_callback_1_0, PPB_Audio_Callback audio_callback_1_1, void *user_data) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } if (!audio_callback_1_0 && !audio_callback_1_1) return PP_ERROR_BADARGUMENT; PP_Resource audio = pp_resource_allocate(PP_RESOURCE_AUDIO, pp_i); struct pp_audio_s *a = pp_resource_acquire(audio, PP_RESOURCE_AUDIO); if (!a) { trace_error("%s, resource allocation failure\n", __func__); return 0; } struct pp_audio_config_s *ac = pp_resource_acquire(audio_config, PP_RESOURCE_AUDIO_CONFIG); if (!ac) { trace_error("%s, bad audio config\n", __func__); goto err; } a->sample_rate = ac->sample_rate; a->sample_frame_count = ac->sample_frame_count; pp_resource_release(audio_config); a->callback_1_0 = audio_callback_1_0; a->callback_1_1 = audio_callback_1_1; a->user_data = user_data; a->stream_ops = audio_select_implementation(); if (a->stream_ops == NULL) { trace_error("%s, no viable audio implementation\n", __func__); goto err; } a->stream = a->stream_ops->create_playback_stream(a->sample_rate, a->sample_frame_count, playback_cb, a); if (!a->stream) { trace_error("%s, can't create playback stream\n", __func__); goto err; } pp_resource_release(audio); return audio; err: pp_resource_release(audio); pp_resource_expunge(audio); return 0; }
PP_Bool ppb_instance_bind_graphics(PP_Instance instance, PP_Resource device) { PP_Bool retval; struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return PP_FALSE; } if (device == 0) { // unbind pthread_mutex_lock(&pp_i->lock); pp_i->graphics = 0; pthread_mutex_unlock(&pp_i->lock); return PP_TRUE; } struct pp_graphics2d_s *g2d = pp_resource_acquire(device, PP_RESOURCE_GRAPHICS2D); struct pp_graphics3d_s *g3d = pp_resource_acquire(device, PP_RESOURCE_GRAPHICS3D); if (g2d) { if (pp_i != g2d->instance) { retval = PP_FALSE; goto done; } pthread_mutex_lock(&pp_i->lock); pp_i->graphics = device; pthread_mutex_unlock(&pp_i->lock); retval = PP_TRUE; } else if (g3d) { if (pp_i != g3d->instance) { retval = PP_FALSE; goto done; } pthread_mutex_lock(&pp_i->lock); pp_i->graphics = device; pthread_mutex_unlock(&pp_i->lock); pp_resource_release(device); retval = PP_TRUE; } else { trace_warning("%s, unsupported graphics resource %d on instance %d\n", __func__, device, instance); retval = PP_FALSE; } done: pp_resource_release(device); return retval; }
PP_Resource ppb_image_data_create(PP_Instance instance, PP_ImageDataFormat format, const struct PP_Size *size, PP_Bool init_to_zero) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource image_data = pp_resource_allocate(PP_RESOURCE_IMAGE_DATA, pp_i); struct pp_image_data_s *id = pp_resource_acquire(image_data, PP_RESOURCE_IMAGE_DATA); if (!id) { trace_error("%s, failed to create image data resource\n", __func__); return 0; } id->format = format; id->width = size->width; id->height = size->height; id->stride = id->width * 4; (void)init_to_zero; // ignore flag, always clear memory id->data = calloc(id->stride * id->height, 1); if (!id->data) { pp_resource_release(image_data); ppb_core_release_resource(image_data); trace_error("%s, can't allocate memory for image\n", __func__); return 0; } id->cairo_surf = cairo_image_surface_create_for_data((void *)id->data, CAIRO_FORMAT_ARGB32, id->width, id->height, id->stride); pp_resource_release(image_data); return image_data; }
PP_Resource ppb_keyboard_input_event_create_1_2(PP_Instance instance, PP_InputEvent_Type type, PP_TimeTicks time_stamp, uint32_t modifiers, uint32_t key_code, struct PP_Var character_text, struct PP_Var code) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource input_event = pp_resource_allocate(PP_RESOURCE_INPUT_EVENT, pp_i); struct pp_input_event_s *ie = pp_resource_acquire(input_event, PP_RESOURCE_INPUT_EVENT); if (!ie) { trace_error("%s, can't allocate memory\n", __func__); return 0; } ie->event_class = PP_INPUTEVENT_CLASS_KEYBOARD; ie->type = type; ie->time_stamp = time_stamp; ie->modifiers = modifiers; ie->key_code = key_code; ie->character_text = character_text; ie->code = code; ppb_var_add_ref(character_text); ppb_var_add_ref(code); pp_resource_release(input_event); return input_event; }
PP_Resource ppb_wheel_input_event_create(PP_Instance instance, PP_TimeTicks time_stamp, uint32_t modifiers, const struct PP_FloatPoint *wheel_delta, const struct PP_FloatPoint *wheel_ticks, PP_Bool scroll_by_page) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource input_event = pp_resource_allocate(PP_RESOURCE_INPUT_EVENT, pp_i); struct pp_input_event_s *ie = pp_resource_acquire(input_event, PP_RESOURCE_INPUT_EVENT); if (!ie) { trace_error("%s, can't allocate memory\n", __func__); return 0; } ie->event_class = PP_INPUTEVENT_CLASS_WHEEL; ie->time_stamp = time_stamp; ie->modifiers = modifiers; ie->wheel_delta.x = wheel_delta ? wheel_delta->x : 0; ie->wheel_delta.y = wheel_delta ? wheel_delta->y : 0; ie->wheel_ticks.x = wheel_ticks ? wheel_ticks->x : 0; ie->wheel_ticks.y = wheel_ticks ? wheel_ticks->y : 0; ie->scroll_by_page = scroll_by_page; pp_resource_release(input_event); return input_event; }
PP_Resource ppb_mouse_input_event_create(PP_Instance instance, PP_InputEvent_Type type, PP_TimeTicks time_stamp, uint32_t modifiers, PP_InputEvent_MouseButton mouse_button, const struct PP_Point *mouse_position, int32_t click_count, const struct PP_Point *mouse_movement) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource input_event = pp_resource_allocate(PP_RESOURCE_INPUT_EVENT, pp_i); struct pp_input_event_s *ie = pp_resource_acquire(input_event, PP_RESOURCE_INPUT_EVENT); if (!ie) { trace_error("%s, can't allocate memory\n", __func__); return 0; } ie->event_class = PP_INPUTEVENT_CLASS_MOUSE; ie->type = type; ie->time_stamp = time_stamp; ie->modifiers = modifiers; ie->mouse_button = mouse_button; ie->mouse_position.x = mouse_position ? mouse_position->x : 0; ie->mouse_position.y = mouse_position ? mouse_position->y : 0; ie->click_count = click_count; ie->mouse_movement.x = mouse_movement ? mouse_movement->x : 0; ie->mouse_movement.y = mouse_movement ? mouse_movement->y : 0; pp_resource_release(input_event); return input_event; }
PP_Resource ppb_video_capture_create(PP_Instance instance) { const struct PPP_VideoCapture_Dev_0_1 *ppp_video_capture_dev; struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } ppp_video_capture_dev = ppp_get_interface(PPP_VIDEO_CAPTURE_DEV_INTERFACE_0_1); if (!ppp_video_capture_dev) { trace_error("%s, no viable %s\n", __func__, PPP_VIDEO_CAPTURE_DEV_INTERFACE_0_1); return 0; } PP_Resource video_capture = pp_resource_allocate(PP_RESOURCE_VIDEO_CAPTURE, pp_i); struct pp_video_capture_s *vc = pp_resource_acquire(video_capture, PP_RESOURCE_VIDEO_CAPTURE); if (!vc) { trace_error("%s, resource allocation failure\n", __func__); return 0; } vc->fd = -1; vc->ppp_video_capture_dev = ppp_video_capture_dev; pp_resource_release(video_capture); return video_capture; }
int32_t ppb_host_resolver_resolve(PP_Resource host_resolver, const char *host, uint16_t port, const struct PP_HostResolver_Private_Hint *hint, struct PP_CompletionCallback callback) { struct pp_host_resolver_s *hr = pp_resource_acquire(host_resolver, PP_RESOURCE_HOST_RESOLVER); if (!hr) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } hr->host = nullsafe_strdup(host); struct async_network_task_s *task = async_network_task_create(); task->type = ASYNC_NETWORK_HOST_RESOLVE; task->resource = host_resolver; task->host = nullsafe_strdup(host); task->port = port; task->callback = callback; task->callback_ml = ppb_message_loop_get_current(); pp_resource_release(host_resolver); async_network_task_push(task); return PP_OK_COMPLETIONPENDING; }
PP_Resource ppb_url_request_info_create(PP_Instance instance) { PP_Resource request_info = pp_resource_allocate(PP_RESOURCE_URL_REQUEST_INFO, instance); struct pp_url_request_info_s *ri = pp_resource_acquire(request_info, PP_RESOURCE_URL_REQUEST_INFO); ri->method = PP_METHOD_UNKNOWN; ri->url = NULL; ri->headers = NULL; ri->stream_to_file = PP_FALSE; ri->follow_redirects = PP_TRUE; ri->record_download_progress = PP_FALSE; ri->record_upload_progress = PP_FALSE; ri->custom_referrer_url = NULL; ri->allow_cross_origin_requests = PP_FALSE; ri->allow_credentials = PP_FALSE; ri->custom_content_transfer_encoding = NULL; ri->prefetch_buffer_upper_threshold = -1; ri->prefetch_buffer_lower_threshold = -1; ri->custom_user_agent = NULL; pp_resource_release(request_info); return request_info; }
int32_t ppb_flash_menu_show(PP_Resource menu_id, const struct PP_Point *location, int32_t *selected_id, struct PP_CompletionCallback callback) { struct pp_flash_menu_s *fm = pp_resource_acquire(menu_id, PP_RESOURCE_FLASH_MENU); if (!fm) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } struct pp_instance_s *pp_i = fm->instance; if (popup_menu_sentinel) trace_error("%s, two context menus at the same time\n", __func__); (void)location; // TODO: handle location popup_menu_sentinel = 1; popup_menu_canceled = 1; popup_menu_ccb = callback; popup_menu_result = selected_id; pthread_mutex_lock(&display.lock); // creating and showing menu together with its closing generates pair of focus events, // FocusOut and FocusIn, which should not be passed to the plugin instance. Otherwise they // will tamper with text selection. pp_i->ignore_focus_events_cnt = 2; pthread_mutex_unlock(&display.lock); ppb_core_call_on_browser_thread(pp_i->id, menu_popup_ptac, fm->menu); pp_resource_release(menu_id); return PP_OK_COMPLETIONPENDING; }
void ppb_graphics2d_paint_image_data(PP_Resource graphics_2d, PP_Resource image_data, const struct PP_Point *top_left, const struct PP_Rect *src_rect) { struct pp_graphics2d_s *g2d = pp_resource_acquire(graphics_2d, PP_RESOURCE_GRAPHICS2D); if (!g2d) { trace_error("%s, bad resource\n", __func__); return; } struct g2d_paint_task_s *pt = g_slice_alloc(sizeof(*pt)); pt->type = gpt_paint_id; pp_resource_ref(image_data); pt->image_data = image_data; pt->src_is_set = !!src_rect; if (top_left) { memcpy(&pt->ofs, top_left, sizeof(*top_left)); } else { pt->ofs.x = pt->ofs.y = 0; } if (src_rect) memcpy(&pt->src, src_rect, sizeof(*src_rect)); g2d->task_list = g_list_append(g2d->task_list, pt); pp_resource_release(graphics_2d); }
PP_Bool ppb_url_request_info_append_data_to_body(PP_Resource request, const void *data, uint32_t len) { struct pp_url_request_info_s *ri = pp_resource_acquire(request, PP_RESOURCE_URL_REQUEST_INFO); if (!ri) { trace_error("%s, bad resource\n", __func__); return PP_FALSE; } PP_Bool retval = PP_FALSE; struct post_data_item_s pdi = { 0 }; pdi.data = g_memdup(data, len); if (!pdi.data) { retval = PP_FALSE; goto err; } pdi.len = len; g_array_append_val(ri->post_data, pdi); retval = PP_TRUE; err: pp_resource_release(request); return retval; }
PP_Resource ppb_url_request_info_create(PP_Instance instance) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource request_info = pp_resource_allocate(PP_RESOURCE_URL_REQUEST_INFO, pp_i); struct pp_url_request_info_s *ri = pp_resource_acquire(request_info, PP_RESOURCE_URL_REQUEST_INFO); if (!ri) { trace_error("%s, resource allocation failure\n", __func__); return 0; } ri->method = PP_METHOD_UNKNOWN; ri->url = NULL; ri->headers = NULL; ri->stream_to_file = PP_FALSE; ri->follow_redirects = PP_TRUE; ri->record_download_progress = PP_FALSE; ri->record_upload_progress = PP_FALSE; ri->custom_referrer_url = NULL; ri->allow_cross_origin_requests = PP_FALSE; ri->allow_credentials = PP_FALSE; ri->custom_content_transfer_encoding = NULL; ri->prefetch_buffer_upper_threshold = -1; ri->prefetch_buffer_lower_threshold = -1; ri->custom_user_agent = NULL; ri->post_data = post_data_new(); pp_resource_release(request_info); return request_info; }
PP_Resource ppb_device_ref_create(PP_Instance instance, struct PP_Var name, struct PP_Var longname, PP_DeviceType_Dev type) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource device_ref = pp_resource_allocate(PP_RESOURCE_DEVICE_REF, pp_i); struct pp_device_ref_s *dr = pp_resource_acquire(device_ref, PP_RESOURCE_DEVICE_REF); if (!dr) { trace_error("%s, resource allocation failure\n", __func__); return 0; } // no type checking is perfomed as it's an internal function dr->name = ppb_var_add_ref2(name); dr->longname = ppb_var_add_ref2(longname); dr->type = type; pp_resource_release(device_ref); return device_ref; }
PP_Bool ppb_url_loader_get_download_progress(PP_Resource loader, int64_t *bytes_received, int64_t *total_bytes_to_be_received) { struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER); if (!ul) { trace_error("%s, bad resource\n", __func__); return PP_FALSE; } *total_bytes_to_be_received = ul->response_size; *bytes_received = 0; if (ul->fd >= 0) { struct stat sb; if (fstat(ul->fd, &sb) != 0) { pp_resource_release(loader); *bytes_received = -1; return PP_FALSE; } *bytes_received = sb.st_size; } pp_resource_release(loader); return PP_TRUE; }
int32_t ppb_url_loader_read_response_body(PP_Resource loader, void *buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback) { struct url_loader_read_task_s *rt; int32_t read_bytes = PP_ERROR_FAILED; struct pp_url_loader_s *ul = pp_resource_acquire(loader, PP_RESOURCE_URL_LOADER); if (!ul) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } if (ul->fd == -1) { trace_error("%s, fd==-1\n", __func__); pp_resource_release(loader); return PP_ERROR_FAILED; } if (ul->read_tasks) { // schedule task instead of immediate reading if there is another task // in the queue already goto schedule_read_task; } read_bytes = -1; off_t ofs = lseek(ul->fd, ul->read_pos, SEEK_SET); if (ofs != (off_t)-1) read_bytes = RETRY_ON_EINTR(read(ul->fd, buffer, bytes_to_read)); if (read_bytes < 0) read_bytes = PP_ERROR_FAILED; else ul->read_pos += read_bytes; if (read_bytes == 0 && !ul->finished_loading) { // no data ready, schedule read task goto schedule_read_task; } pp_resource_release(loader); if (callback.flags & PP_COMPLETIONCALLBACK_FLAG_OPTIONAL) return read_bytes; ppb_message_loop_post_work_with_result(ppb_message_loop_get_current(), callback, 0, read_bytes, 0, __func__); return PP_OK_COMPLETIONPENDING; schedule_read_task: rt = g_slice_alloc(sizeof(*rt)); rt->url_loader = loader; rt->buffer = buffer; rt->bytes_to_read = bytes_to_read; rt->ccb = callback; rt->ccb_ml = ppb_message_loop_get_current(); ul->read_tasks = g_list_append(ul->read_tasks, rt); pp_resource_release(loader); return PP_OK_COMPLETIONPENDING; }
void ppb_image_data_unmap(PP_Resource image_data) { struct pp_image_data_s *id = pp_resource_acquire(image_data, PP_RESOURCE_IMAGE_DATA); if (!id) return; pp_resource_release(image_data); }
PP_Resource ppb_graphics2d_create(PP_Instance instance, const struct PP_Size *size, PP_Bool is_always_opaque) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource graphics_2d = pp_resource_allocate(PP_RESOURCE_GRAPHICS2D, pp_i); struct pp_graphics2d_s *g2d = pp_resource_acquire(graphics_2d, PP_RESOURCE_GRAPHICS2D); if (!g2d) { trace_error("%s, can't create graphics2d resource\n", __func__); return 0; } g2d->is_always_opaque = is_always_opaque; g2d->scale = config.device_scale; g2d->width = size->width; g2d->height = size->height; g2d->stride = 4 * size->width; g2d->scaled_width = g2d->width * g2d->scale + 0.5; g2d->scaled_height = g2d->height * g2d->scale + 0.5; g2d->scaled_stride = 4 * g2d->scaled_width; g2d->data = calloc(g2d->stride * g2d->height, 1); g2d->second_buffer = calloc(g2d->scaled_stride * g2d->scaled_height, 1); if (!g2d->data || !g2d->second_buffer) { trace_warning("%s, can't allocate memory\n", __func__); free_and_nullify(g2d->data); free_and_nullify(g2d->second_buffer); pp_resource_release(graphics_2d); ppb_core_release_resource(graphics_2d); return 0; } g2d->cairo_surf = cairo_image_surface_create_for_data((unsigned char *)g2d->data, CAIRO_FORMAT_ARGB32, g2d->width, g2d->height, g2d->stride); g2d->task_list = NULL; if (pp_i->is_transparent) { // we need XRender picture (which in turn requires X Pixmap) to alpha blend // our images with existing pixmap provided by the browser. This is only needed // is instance is transparent, therefore depth is always 32-bit. pthread_mutex_lock(&display.lock); g2d->pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), g2d->scaled_width, g2d->scaled_height, 32); XFlush(display.x); g2d->xr_pict = XRenderCreatePicture(display.x, g2d->pixmap, display.pictfmt_argb32, 0, 0); g2d->gc = XCreateGC(display.x, g2d->pixmap, 0, 0); XFlush(display.x); pthread_mutex_unlock(&display.lock); } pp_resource_release(graphics_2d); return graphics_2d; }
uint32_t ppb_audio_config_get_sample_frame_count(PP_Resource config) { struct pp_audio_config_s *ac = pp_resource_acquire(config, PP_RESOURCE_AUDIO_CONFIG); if (!ac) return 0; uint32_t sample_frame_count = ac->sample_frame_count; pp_resource_release(config); return sample_frame_count; }
PP_AudioSampleRate ppb_audio_config_get_sample_rate(PP_Resource config) { struct pp_audio_config_s *ac = pp_resource_acquire(config, PP_RESOURCE_AUDIO_CONFIG); if (!ac) return PP_AUDIOSAMPLERATE_NONE; PP_AudioSampleRate sample_rate = ac->sample_rate; pp_resource_release(config); return sample_rate; }
void ppb_image_data_unmap(PP_Resource image_data) { struct pp_image_data_s *id = pp_resource_acquire(image_data, PP_RESOURCE_IMAGE_DATA); if (!id) { trace_error("%s, bad resource\n", __func__); return; } pp_resource_release(image_data); }
void ppb_tcp_socket_disconnect(PP_Resource tcp_socket) { struct pp_tcp_socket_s *ts = pp_resource_acquire(tcp_socket, PP_RESOURCE_TCP_SOCKET); if (!ts) { trace_error("%s, bad resource\n", __func__); return; } ppb_tcp_socket_destroy(ts); pp_resource_release(tcp_socket); }
PP_InputEvent_Type ppb_input_event_get_type(PP_Resource event) { struct pp_input_event_s *ie = pp_resource_acquire(event, PP_RESOURCE_INPUT_EVENT); if (!ie) { trace_error("%s, bad resource\n", __func__); return PP_INPUTEVENT_TYPE_UNDEFINED; } PP_InputEvent_Type t = ie->type; pp_resource_release(event); return t; }