static void _execute_script_comt(void *user_data, int32_t result) { struct execute_script_param_s *esp = user_data; ppb_core_call_on_browser_thread(_execute_script_ptac, esp); }
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; }
static void n2p_deallocate_comt(void *user_data, int32_t result) { struct deallocate_param_s *p = user_data; ppb_core_call_on_browser_thread(0, n2p_deallocate_ptac, p); }
static void n2p_has_property_comt(void *user_data, int32_t result) { struct has_property_param_s *p = user_data; ppb_core_call_on_browser_thread(0, n2p_has_property_ptac, p); }
static void _get_document_url_comt(void *user_data, int32_t result) { struct get_document_url_param_s *p = user_data; ppb_core_call_on_browser_thread(_get_document_url_ptac, p); }
static void _url_loader_open_comt(void *user_data, int32_t result) { struct url_loader_open_param_s *p = user_data; ppb_core_call_on_browser_thread(_url_loader_open_ptac, p); }
void ppb_text_input_interface_set_text_input_type(PP_Instance instance, PP_TextInput_Type_Dev type) { struct set_text_input_type_param_s *p = g_slice_alloc0(sizeof(*p)); p->instance = instance; p->type = type; ppb_core_call_on_browser_thread(instance, set_text_input_type_ptac, p); }
void ppb_flash_menu_destroy(void *p) { struct pp_flash_menu_s *fm = p; g_object_ref_sink(fm->menu); // actual menu destroy can make something X-related, call in on browser thread ppb_core_call_on_browser_thread(fm->instance->id, destroy_flash_menu_ptac, fm->menu); }
void ppb_text_input_interface_update_surrounding_text(PP_Instance instance, const char *text, uint32_t caret, uint32_t anchor) { struct update_surrounding_text_param_s *p = g_slice_alloc0(sizeof(*p)); p->instance = instance; p->text = g_strdup(text); p->caret = caret; ppb_core_call_on_browser_thread(instance, update_surrounding_text_ptac, p); return; }
void ppb_text_input_interface_update_caret_position(PP_Instance instance, const struct PP_Rect *caret, const struct PP_Rect *bounding_box) { if (!caret) return; struct update_caret_position_param_s *p = g_slice_alloc0(sizeof(*p)); p->instance = instance; p->caret.x = caret->point.x; p->caret.y = caret->point.y; p->caret.width = caret->size.width; p->caret.height = caret->size.height; ppb_core_call_on_browser_thread(instance, update_caret_position_ptac, p); }
PP_Bool ppb_audio_stop_playback(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 PP_FALSE; } a->stream_ops->pause(a->stream, 1); if (a->is_playing) { g_atomic_int_add(&a->instance->audio_source_count, -1); a->is_playing = 0; } pp_resource_release(audio); ppb_core_call_on_browser_thread(a->instance->id, update_instance_playing_audio_status_ptac, GSIZE_TO_POINTER(a->instance->id)); return PP_TRUE; }
static void flash_menu_create_comt(void *user_data, int32_t result) { ppb_core_call_on_browser_thread(0, flash_menu_create_ptac, user_data); }
static void _call_invalidaterect_ptac(void *param) { struct pp_instance_s *pp_i = tables_get_pp_instance(GPOINTER_TO_SIZE(param)); if (!pp_i) return; NPRect npr = {.top = 0, .left = 0, .bottom = pp_i->height, .right = pp_i->width}; npn.invalidaterect(pp_i->npp, &npr); npn.forceredraw(pp_i->npp); } int32_t ppb_graphics3d_swap_buffers(PP_Resource context, struct PP_CompletionCallback callback) { struct pp_graphics3d_s *g3d = pp_resource_acquire(context, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } struct pp_instance_s *pp_i = g3d->instance; pthread_mutex_lock(&display.lock); if (pp_i->graphics != context) { // Other context bound, do nothing. pp_resource_release(context); pthread_mutex_unlock(&display.lock); return PP_ERROR_FAILED; } if (pp_i->graphics_in_progress) { pp_resource_release(context); pthread_mutex_unlock(&display.lock); return PP_ERROR_INPROGRESS; } eglMakeCurrent(display.egl, g3d->egl_surf, g3d->egl_surf, g3d->glc); if (pp_i->is_transparent) { glBindTexture(GL_TEXTURE_2D, g3d->tex_front); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, g3d->width, g3d->height, 0); } glFinish(); // ensure painting is done eglMakeCurrent(display.egl, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); pp_resource_release(context); pp_i->graphics_ccb = callback; pp_i->graphics_in_progress = 1; if (!callback.func) pthread_barrier_init(&pp_i->graphics_barrier, NULL, 2); if (pp_i->is_fullscreen) { XGraphicsExposeEvent ev = { .type = GraphicsExpose, .drawable = pp_i->fs_wnd, .width = display.fs_width, .height = display.fs_height, }; XSendEvent(display.x, pp_i->fs_wnd, True, ExposureMask, (void *)&ev); XFlush(display.x); pthread_mutex_unlock(&display.lock); } else { pthread_mutex_unlock(&display.lock); ppb_core_call_on_browser_thread(_call_invalidaterect_ptac, GSIZE_TO_POINTER(pp_i->id)); } if (callback.func) return PP_OK_COMPLETIONPENDING; pthread_barrier_wait(&pp_i->graphics_barrier); return PP_OK; }
static void clipboard_read_data_comt(void *user_data, int32_t result) { ppb_core_call_on_browser_thread(0, clipboard_read_data_ptac, user_data); }
PP_Bool ppb_flash_draw_glyphs(PP_Instance instance, PP_Resource pp_image_data, const struct PP_BrowserFont_Trusted_Description *font_desc, uint32_t color, const struct PP_Point *position, const struct PP_Rect *clip, const float transformation[3][3], PP_Bool allow_subpixel_aa, uint32_t glyph_count, const uint16_t glyph_indices[], const struct PP_Point glyph_advances[]) { struct pp_image_data_s *id = pp_resource_acquire(pp_image_data, PP_RESOURCE_IMAGE_DATA); if (!id) { trace_error("%s, bad resource\n", __func__); return PP_FALSE; } cairo_t *cr = cairo_create(id->cairo_surf); const char *font_family; if (font_desc->face.type == PP_VARTYPE_STRING) { font_family = ppb_var_var_to_utf8(font_desc->face, NULL); } else { switch (font_desc->family) { case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF: font_family = "serif"; break; case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF: font_family = "sans-serif"; break; case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE: font_family = "monospace"; break; default: font_family = ""; break; } } cairo_select_font_face(cr, font_family, font_desc->italic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL, font_desc->weight >= (int)PP_FONTWEIGHT_700 ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, font_desc->size); if (allow_subpixel_aa) { cairo_font_options_t *options = cairo_font_options_create(); cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL); cairo_set_font_options(cr, options); cairo_font_options_destroy(options); } if (clip) { cairo_rectangle(cr, clip->point.x, clip->point.y, clip->size.width, clip->size.height); cairo_clip(cr); } 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); cairo_matrix_t matrix; cairo_matrix_init(&matrix, transformation[0][0], transformation[0][1], transformation[1][0], transformation[1][1], transformation[0][2], transformation[1][2]); cairo_set_matrix(cr, &matrix); cairo_glyph_t *c_glyphs = malloc(glyph_count * sizeof(cairo_glyph_t)); struct PP_Point current = {.x = 0, .y = 0}; for (uint32_t k = 0; k < glyph_count; k ++) { c_glyphs[k].index = glyph_indices[k]; c_glyphs[k].x = current.x; c_glyphs[k].y = current.y; current.x += glyph_advances[k].x; current.y += glyph_advances[k].y; } cairo_show_glyphs(cr, c_glyphs, glyph_count); free(c_glyphs); cairo_surface_flush(id->cairo_surf); cairo_destroy(cr); pp_resource_release(pp_image_data); return PP_TRUE; } struct get_proxy_for_url_param_s { PP_Instance instance_id; const char *url; struct PP_Var result; PP_Resource m_loop; int depth; }; static void get_proxy_for_url_ptac(void *user_data) { struct get_proxy_for_url_param_s *p = user_data; struct pp_instance_s *pp_i = tables_get_pp_instance(p->instance_id); p->result = PP_MakeUndefined(); if (pp_i && pp_i->npp && npn.getvalueforurl) { char *value = NULL; uint32_t len = 0; NPError err; err = npn.getvalueforurl(pp_i->npp, NPNURLVProxy, p->url, &value, &len); if (err == NPERR_NO_ERROR) { p->result = ppb_var_var_from_utf8(value, len); } } ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth); } static void get_proxy_for_url_comt(void *user_data, int32_t result) { ppb_core_call_on_browser_thread(0, get_proxy_for_url_ptac, user_data); }
void ppb_text_input_interface_cancel_composition_text(PP_Instance instance) { ppb_core_call_on_browser_thread(instance, cancel_composition_text_ptac, GSIZE_TO_POINTER(instance)); }
static void _call_invalidaterect_ptac(void *param) { struct pp_instance_s *pp_i = param; NPRect npr = {.top = 0, .left = 0, .bottom = pp_i->height, .right = pp_i->width}; npn.invalidaterect(pp_i->npp, &npr); npn.forceredraw(pp_i->npp); } int32_t ppb_graphics2d_flush(PP_Resource graphics_2d, struct PP_CompletionCallback callback) { struct pp_graphics2d_s *g2d = pp_resource_acquire(graphics_2d, PP_RESOURCE_GRAPHICS2D); if (!g2d) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } struct pp_instance_s *pp_i = g2d->instance; pthread_mutex_lock(&pp_i->lock); if (pp_i->graphics != graphics_2d) { pp_resource_release(graphics_2d); pthread_mutex_unlock(&pp_i->lock); return PP_ERROR_FAILED; } if (pp_i->graphics_in_progress) { pp_resource_release(graphics_2d); pthread_mutex_unlock(&pp_i->lock); return PP_ERROR_INPROGRESS; } pp_i->graphics_ccb = callback; pp_i->graphics_in_progress = 1; pthread_mutex_unlock(&pp_i->lock); while (g2d->task_list) { GList *link = g_list_first(g2d->task_list); struct g2d_paint_task_s *pt = link->data; struct pp_image_data_s *id; cairo_t *cr; g2d->task_list = g_list_delete_link(g2d->task_list, link); switch (pt->type) { case gpt_paint_id: id = pp_resource_acquire(pt->image_data, PP_RESOURCE_IMAGE_DATA); if (!id) break; cairo_surface_mark_dirty(g2d->cairo_surf); cr = cairo_create(g2d->cairo_surf); cairo_set_source_surface(cr, id->cairo_surf, pt->ofs.x, pt->ofs.y); if (pt->src_is_set) { cairo_rectangle(cr, pt->src.point.x + pt->ofs.x, pt->src.point.y + pt->ofs.y, pt->src.size.width, pt->src.size.height); cairo_fill(cr); } else { cairo_paint(cr); } cairo_surface_flush(g2d->cairo_surf); cairo_destroy(cr); pp_resource_release(pt->image_data); pp_resource_unref(pt->image_data); break; case gpt_replace_contents: id = pp_resource_acquire(pt->image_data, PP_RESOURCE_IMAGE_DATA); if (!id) break; if (id->width == g2d->width || id->height == g2d->height) { void *tmp; cairo_surface_t *tmp_surf; cairo_surface_flush(id->cairo_surf); cairo_surface_flush(g2d->cairo_surf); tmp = g2d->data; g2d->data = id->data; id->data = tmp; tmp_surf = g2d->cairo_surf; g2d->cairo_surf = id->cairo_surf; id->cairo_surf = tmp_surf; } pp_resource_release(pt->image_data); pp_resource_unref(pt->image_data); break; } g_slice_free(struct g2d_paint_task_s, pt); } // scale image { cairo_surface_t *surf; surf = cairo_image_surface_create_for_data((unsigned char *)g2d->second_buffer, CAIRO_FORMAT_ARGB32, g2d->scaled_width, g2d->scaled_height, g2d->scaled_stride); cairo_t *cr = cairo_create(surf); cairo_scale(cr, g2d->scale, g2d->scale); cairo_set_source_surface(cr, g2d->cairo_surf, 0, 0); cairo_paint(cr); cairo_destroy(cr); cairo_surface_destroy(surf); } pp_resource_release(graphics_2d); pthread_mutex_lock(&pp_i->lock); if (!callback.func) pthread_barrier_init(&pp_i->graphics_barrier, NULL, 2); if (pp_i->is_fullscreen) { XGraphicsExposeEvent ev = { .type = GraphicsExpose, .drawable = pp_i->fs_wnd, .width = pp_i->width, .height = pp_i->height }; XSendEvent(pp_i->dpy, pp_i->fs_wnd, True, ExposureMask, (void *)&ev); XFlush(pp_i->dpy); pthread_mutex_unlock(&pp_i->lock); } else { pthread_mutex_unlock(&pp_i->lock); ppb_core_call_on_browser_thread(_call_invalidaterect_ptac, pp_i); } if (callback.func) return PP_OK_COMPLETIONPENDING; pthread_barrier_wait(&pp_i->graphics_barrier); return PP_OK; }
static void clipboard_is_format_available_comt(void *user_data, int32_t result) { ppb_core_call_on_browser_thread(0, clipboard_is_format_available_ptac, user_data); }
static void topmost_rect_comt(void *user_data, int32_t result) { ppb_core_call_on_browser_thread(0, topmost_rect_ptac, user_data); }
PP_Bool ppb_cursor_control_set_cursor(PP_Instance instance, enum PP_CursorType_Dev type, PP_Resource custom_image, const struct PP_Point *hot_spot) { int xtype = XC_arrow; int hide_cursor = 0; switch (type) { case PP_CURSORTYPE_CUSTOM: xtype = XC_arrow; break; case PP_CURSORTYPE_POINTER: xtype = XC_left_ptr; break; case PP_CURSORTYPE_CROSS: xtype = XC_crosshair; break; case PP_CURSORTYPE_HAND: xtype = XC_hand2; break; case PP_CURSORTYPE_IBEAM: xtype = XC_xterm; break; case PP_CURSORTYPE_WAIT: xtype = XC_watch; break; case PP_CURSORTYPE_HELP: xtype = XC_question_arrow; break; case PP_CURSORTYPE_EASTRESIZE: xtype = XC_right_side; break; case PP_CURSORTYPE_NORTHRESIZE: xtype = XC_top_side; break; case PP_CURSORTYPE_NORTHEASTRESIZE: xtype = XC_top_right_corner; break; case PP_CURSORTYPE_NORTHWESTRESIZE: xtype = XC_top_left_corner; break; case PP_CURSORTYPE_SOUTHRESIZE: xtype = XC_bottom_side; break; case PP_CURSORTYPE_SOUTHEASTRESIZE: xtype = XC_bottom_right_corner; break; case PP_CURSORTYPE_SOUTHWESTRESIZE: xtype = XC_bottom_left_corner; break; case PP_CURSORTYPE_WESTRESIZE: xtype = XC_left_side; break; case PP_CURSORTYPE_NORTHSOUTHRESIZE: xtype = XC_sb_v_double_arrow; break; case PP_CURSORTYPE_EASTWESTRESIZE: xtype = XC_sb_h_double_arrow; break; case PP_CURSORTYPE_NORTHEASTSOUTHWESTRESIZE: xtype = XC_left_ptr; break; case PP_CURSORTYPE_NORTHWESTSOUTHEASTRESIZE: xtype = XC_left_ptr; break; case PP_CURSORTYPE_COLUMNRESIZE: xtype = XC_sb_h_double_arrow; break; case PP_CURSORTYPE_ROWRESIZE: xtype = XC_sb_v_double_arrow; break; case PP_CURSORTYPE_MIDDLEPANNING: xtype = XC_fleur; break; case PP_CURSORTYPE_EASTPANNING: xtype = XC_sb_right_arrow; break; case PP_CURSORTYPE_NORTHPANNING: xtype = XC_sb_up_arrow; break; case PP_CURSORTYPE_NORTHEASTPANNING: xtype = XC_top_right_corner; break; case PP_CURSORTYPE_NORTHWESTPANNING: xtype = XC_top_left_corner; break; case PP_CURSORTYPE_SOUTHPANNING: xtype = XC_sb_down_arrow; break; case PP_CURSORTYPE_SOUTHEASTPANNING: xtype = XC_bottom_right_corner; break; case PP_CURSORTYPE_SOUTHWESTPANNING: xtype = XC_bottom_left_corner; break; case PP_CURSORTYPE_WESTPANNING: xtype = XC_sb_left_arrow; break; case PP_CURSORTYPE_MOVE: xtype = XC_fleur; break; case PP_CURSORTYPE_VERTICALTEXT: xtype = XC_left_ptr; break; case PP_CURSORTYPE_CELL: xtype = XC_left_ptr; break; case PP_CURSORTYPE_CONTEXTMENU: xtype = XC_left_ptr; break; case PP_CURSORTYPE_ALIAS: xtype = XC_left_ptr; break; case PP_CURSORTYPE_PROGRESS: xtype = XC_watch; break; case PP_CURSORTYPE_NODROP: xtype = XC_left_ptr; break; case PP_CURSORTYPE_COPY: xtype = XC_left_ptr; break; case PP_CURSORTYPE_NONE: xtype = XC_left_ptr; hide_cursor = 1; break; case PP_CURSORTYPE_NOTALLOWED: xtype = XC_left_ptr; break; case PP_CURSORTYPE_ZOOMIN: xtype = XC_left_ptr; break; case PP_CURSORTYPE_ZOOMOUT: xtype = XC_left_ptr; break; case PP_CURSORTYPE_GRAB: xtype = XC_left_ptr; break; case PP_CURSORTYPE_GRABBING: xtype = XC_left_ptr; break; } struct comt_param_s *comt_params = g_slice_alloc0(sizeof(*comt_params)); comt_params->instance_id = instance; comt_params->xtype = xtype; comt_params->hide_cursor = hide_cursor; comt_params->custom_image = (type == PP_CURSORTYPE_CUSTOM) ? custom_image : 0; if (hot_spot) { comt_params->hotspot_x = hot_spot->x; comt_params->hotspot_y = hot_spot->y; } ppb_core_call_on_browser_thread(instance, set_cursor_ptac, comt_params); return PP_TRUE; }