static
void
n2p_construct_ptac(void *param)
{
    struct construct_param_s *p = param;
    NPP npp = tables_get_npobj_npp_mapping(p->object);

    NPVariant *np_args = malloc(p->argc * sizeof(NPVariant));
    for (uint32_t k = 0; k < p->argc; k ++)
        np_args[k] = pp_var_to_np_variant(p->argv[k]);

    NPVariant np_result;
    bool res = npp ? npn.construct(npp, p->object, np_args, p->argc, &np_result) : FALSE;

    for (uint32_t k = 0; k < p->argc; k ++)
        npn.releasevariantvalue(&np_args[k]);
    free(np_args);

    if (res) {
        struct PP_Var var = np_variant_to_pp_var(np_result);

        if (np_result.type == NPVariantType_Object)
            tables_add_npobj_npp_mapping(np_result.value.objectValue, npp);
        else
            npn.releasevariantvalue(&np_result);

        p->result = var;
    } else {
        p->result = PP_MakeUndefined();
    }

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
Esempio n. 2
0
static
void
_execute_script_ptac(void *user_data)
{
    struct execute_script_param_s *p = user_data;
    NPString  np_script;
    NPVariant np_result;

    // no need to lock, this function is run only in browser thread
    if (!p->pp_i->npp) {
        trace_error("%s, plugin instance was destroyed\n", __func__);
        p->result = PP_MakeUndefined();
        goto quit;
    }

    np_script.UTF8Characters = ppb_var_var_to_utf8(p->script, &np_script.UTF8Length);
    if (!npn.evaluate(p->pp_i->npp, p->pp_i->np_window_obj, &np_script, &np_result)) {
        trace_error("%s, NPN_Evaluate failed\n", __func__);
        p->result = PP_MakeUndefined();
        goto quit;
    }

    // TODO: find out what exception is
    p->result = np_variant_to_pp_var(np_result);
    if (np_result.type == NPVariantType_Object)
        tables_add_npobj_npp_mapping(np_result.value.objectValue, p->pp_i->npp);
    else
        npn.releasevariantvalue(&np_result);

quit:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
Esempio n. 3
0
static
void
call_plugin_shutdown_module_comt(void *user_data, int32_t result)
{
    struct call_plugin_shutdown_module_param_s *p = user_data;
    p->ppp_shutdown_module();   // p->ppp_shutdown_module is always non-NULL
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
Esempio n. 4
0
static
void
call_plugin_init_module_comt(void *user_data, int32_t result)
{
    struct call_plugin_init_module_param_s *p = user_data;

    // TODO: make module ids distinct
    // p->ppp_initialize_module is always non-NULL
    p->result = p->ppp_initialize_module(42, ppb_get_interface);

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
void
ppb_flash_message_loop_quit(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;
    }
    if (fml->running)
        ppb_message_loop_post_quit_depth(fml->message_loop, PP_FALSE, fml->depth);
    pp_resource_release(flash_message_loop);
}
Esempio n. 6
0
static
void
topmost_rect_ptac(void *param)
{
    struct topmost_rect_param_s *p = param;
    struct pp_instance_s *pp_i = tables_get_pp_instance(p->instance);
    if (!pp_i) {
        trace_error("%s, no instance\n", __func__);
        goto err_1;
    }

    p->result = PP_FALSE;

    NPString topmost_func_src = NPString_literal(
        "(function(elem, x, y) {"
            "var r = elem.getBoundingClientRect();"
            "return document.elementFromPoint(x + r.left, y + r.top) == elem;"
        "})");
    NPVariant topmost_func;

    if (!npn.evaluate(pp_i->npp, pp_i->np_window_obj, &topmost_func_src, &topmost_func))
        goto err_1;

    if (!NPVARIANT_IS_OBJECT(topmost_func))
        goto err_1;

    NPObject *topmost_func_obj = NPVARIANT_TO_OBJECT(topmost_func);

    NPVariant is_topmost;
    NPVariant args[3];

    OBJECT_TO_NPVARIANT(pp_i->np_plugin_element_obj, args[0]);
    INT32_TO_NPVARIANT(p->rect.point.x + p->rect.size.width / 2, args[1]);
    INT32_TO_NPVARIANT(p->rect.point.y + p->rect.size.height / 2, args[2]);

    if (!npn.invokeDefault(pp_i->npp, topmost_func_obj, args, 3, &is_topmost))
        goto err_2;

    if (!NPVARIANT_IS_BOOLEAN(is_topmost))
        goto err_3;

    p->result = NPVARIANT_TO_BOOLEAN(is_topmost);

err_3:
    npn.releasevariantvalue(&is_topmost);
err_2:
    npn.releasevariantvalue(&topmost_func);
err_1:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
n2p_has_property_ptac(void *param)
{
    struct has_property_param_s *p = param;
    const char *s_name = ppb_var_var_to_utf8(p->name, NULL);
    NPIdentifier identifier = npn.getstringidentifier(s_name);
    NPP npp = tables_get_npobj_npp_mapping(p->object);

    if (npp)
        p->result = npn.hasproperty(npp, p->object, identifier);
    else
        p->result = false;
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
p2n_enumerate_comt(void *user_data, int32_t result)
{
    struct enumerate_param_s *p = user_data;
    struct np_proxy_object_s *obj = (void *)p->npobj;
    struct PP_Var exception;

    p->count = 0;
    p->values = NULL;
    p->result = true;

    ppb_var_get_all_property_names(obj->ppobj, &p->count, &p->values, &exception);

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
n2p_deallocate_ptac(void *param)
{
    struct deallocate_param_s *p = param;

    NPObject *np_object = p->object;
    uint32_t ref_cnt = np_object->referenceCount;

    npn.releaseobject(p->object);

    if (ref_cnt <= 1)
        tables_remove_npobj_npp_mapping(p->object);

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
p2n_has_method_comt(void *user_data, int32_t result)
{
    struct has_method_param_s *p = user_data;
    struct np_proxy_object_s *obj = (void *)p->npobj;
    struct PP_Var exception = PP_MakeUndefined();
    struct PP_Var method_name = ppb_var_var_from_utf8_z(p->name);

    p->result = ppb_var_has_method(obj->ppobj, method_name, &exception);

    ppb_var_release(method_name);
    ppb_var_release(exception);

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
p2n_get_property_comt(void *user_data, int32_t result)
{
    struct get_property_param_s *p = user_data;
    struct np_proxy_object_s *obj = (void *)p->npobj;
    struct PP_Var exception = PP_MakeUndefined();
    struct PP_Var property_name = ppb_var_var_from_utf8_z(p->name);
    struct PP_Var res = ppb_var_get_property(obj->ppobj, property_name, &exception);

    p->result = true;
    *p->np_result = pp_var_to_np_variant(res);
    ppb_var_release(res);
    ppb_var_release(exception);

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
clipboard_is_format_available_ptac(void *user_data)
{
    struct clipboard_is_format_available_param_s *p = user_data;

    p->result = PP_FALSE;
    GtkClipboard *clipboard = get_clipboard_of_type(p->clipboard_type);
    if (!clipboard)
        goto quit;

    GdkAtom target = get_clipboard_target_atom(p->format);
    if (target == GDK_NONE)
        goto quit;

    p->result = gw_gtk_clipboard_wait_is_target_available(clipboard, target);

quit:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
Esempio n. 13
0
static
void
_get_document_url_ptac(void *user_data)
{
    struct get_document_url_param_s *p = user_data;

    p->result = ppb_var_var_from_utf8("", 0);
    NPIdentifier location_id = npn.getstringidentifier("location");
    NPIdentifier href_id = npn.getstringidentifier("href");
    NPObject *np_location_obj;
    NPVariant location_var, href_var;

    if (!npn.getproperty(p->npp, p->np_window_obj, location_id, &location_var))
        goto err_2;

    if (location_var.type != NPVariantType_Object)
        goto err_3;

    np_location_obj = location_var.value.objectValue;
    if (!npn.getproperty(p->npp, np_location_obj, href_id, &href_var))
        goto err_3;


    struct PP_Var var = np_variant_to_pp_var(href_var);
    if (var.type != PP_VARTYPE_STRING) {
        ppb_var_release(var);
        goto err_4;
    }

    ppb_var_release(p->result);
    p->result = var;


err_4:
    npn.releasevariantvalue(&href_var);
err_3:
    npn.releasevariantvalue(&location_var);
err_2:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
    return;
}
static
void
flash_menu_create_ptac(void *param)
{
    struct flash_menu_create_param_s *p = param;
    struct pp_flash_menu_s *fm = pp_resource_acquire(p->flash_menu, PP_RESOURCE_FLASH_MENU);
    if (!fm) {
        trace_error("%s, bad resource\n", __func__);
        goto quit;
    }

    // recursively construct menu
    fm->menu = convert_menu(p->menu_data);

    // we need notification on menu close
    g_signal_connect(fm->menu, "selection-done", G_CALLBACK(menu_selection_done), NULL);

    pp_resource_release(p->flash_menu);
quit:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
p2n_invoke_comt(void *user_data, int32_t result)
{
    struct invoke_param_s *p = user_data;
    unsigned int k;

    p->result = true;
    struct np_proxy_object_s *obj = (void *)p->npobj;
    struct PP_Var exception = PP_MakeUndefined();
    struct PP_Var method_name = ppb_var_var_from_utf8_z(p->name);
    struct PP_Var res;

    struct PP_Var *pp_args = malloc(p->argCount * sizeof(*pp_args));
    for (k = 0; k < p->argCount; k ++) {
        pp_args[k] = np_variant_to_pp_var(p->args[k]);
    }

    res = ppb_var_call(obj->ppobj, method_name, p->argCount, pp_args, &exception);

    for (k = 0; k < p->argCount; k ++)
        ppb_var_release(pp_args[k]);
    free(pp_args);

    if (p->np_result) {
        *p->np_result = pp_var_to_np_variant(res);
        if (p->np_result->type == NPVariantType_Object) {
            NPP npp = tables_get_npobj_npp_mapping(p->npobj);
            tables_add_npobj_npp_mapping(p->np_result->value.objectValue, npp);
        }
    }

    ppb_var_release(res);
    ppb_var_release(method_name);
    ppb_var_release(exception);

    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
clipboard_read_data_ptac(void *user_data)
{
    struct clipboard_read_data_param_s *p = user_data;

    p->result = PP_MakeUndefined();
    GtkClipboard *clipboard = get_clipboard_of_type(p->clipboard_type);
    if (!clipboard)
        goto quit;

    GdkAtom target = get_clipboard_target_atom(p->format);
    if (target == GDK_NONE)
        goto quit;

    GtkSelectionData *sd = gw_gtk_clipboard_wait_for_contents(clipboard, target);
    if (sd) {
        const guchar *sd_data = gw_gtk_selection_data_get_data(sd);
        const gint sd_length = gw_gtk_selection_data_get_length(sd);
        switch (p->format) {
        case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT:
        case PP_FLASH_CLIPBOARD_FORMAT_HTML:
            p->result = ppb_var_var_from_utf8((char *)sd_data, sd_length);
            break;
        default:
            p->result = ppb_var_array_buffer_create(sd_length);
            memcpy(ppb_var_array_buffer_map(p->result), sd_data, sd_length);
            ppb_var_array_buffer_unmap(p->result);
            break;
        }

        gw_gtk_selection_data_free(sd);
    }

quit:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
static
void
n2p_get_property_ptac(void *param)
{
    struct get_property_param_s *p = param;
    const char *s_name = ppb_var_var_to_utf8(p->name, NULL);
    NPIdentifier identifier = npn.getstringidentifier(s_name);
    NPVariant np_value;
    NPP npp = tables_get_npobj_npp_mapping(p->object);

    if (npp && npn.getproperty(npp, p->object, identifier, &np_value)) {
        struct PP_Var var = np_variant_to_pp_var(np_value);

        if (np_value.type == NPVariantType_Object)
            tables_add_npobj_npp_mapping(np_value.value.objectValue, npp);
        else
            npn.releasevariantvalue(&np_value);

        p->result = var;
    } else {
        p->result = PP_MakeUndefined();
    }
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
int32_t
ppb_message_loop_run_int(PP_Resource message_loop, int nested, int increase_depth)
{
    if (this_thread_message_loop != message_loop) {
        trace_error("%s, not attached to current thread\n", __func__);
        return PP_ERROR_WRONG_THREAD;
    }

    struct pp_message_loop_s *ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP);
    if (!ml) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    // prevent nested loops
    if (!nested && ml->running) {
        trace_error("%s, trying to run nested loop without declaring as nested\n", __func__);
        pp_resource_release(message_loop);
        return PP_ERROR_INPROGRESS;
    }

    struct {
        int running;
        int teardown;
    } saved_state = {
        .running = ml->running,
        .teardown = ml->teardown,
    };

    ml->running = 1;
    ml->teardown = 0;
    if (increase_depth)
        ml->depth++;

    int teardown = 0;
    int destroy_ml = 0;
    int depth = ml->depth;
    pp_resource_ref(message_loop);
    GAsyncQueue *async_q = ml->async_q;
    GQueue *int_q = ml->int_q;
    pp_resource_release(message_loop);

    while (1) {
        struct timespec now;
        struct message_loop_task_s *task = g_queue_peek_head(int_q);
        gint64 timeout = 1000 * 1000;
        if (task) {
            clock_gettime(CLOCK_REALTIME, &now);
            timeout = (task->when.tv_sec - now.tv_sec) * 1000 * 1000 +
                      (task->when.tv_nsec - now.tv_nsec) / 1000;
            if (timeout <= 0) {
                // remove task from the queue
                g_queue_pop_head(int_q);

                // check if depth is correct
                if (task->depth > 0 && task->depth < depth) {
                    // wrong, reschedule it a bit later
                    task->when = add_ms(now, 10);
                    g_queue_insert_sorted(int_q, task, time_compare_func, NULL);
                    continue;
                }

                if (task->terminate) {
                    if (depth > 1) {
                        // exit at once, all remaining task will be processed by outer loop
                        g_slice_free(struct message_loop_task_s, task);
                        break;
                    }

                    // it's the outermost loop, we should wait for all tasks to be run
                    ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP);
                    if (ml) {
                        ml->teardown = 1;
                        teardown = 1;
                        destroy_ml = task->should_destroy_ml;
                        pp_resource_release(message_loop);
                    }

                    g_slice_free(struct message_loop_task_s, task);
                    continue;
                }

                // run task
                const struct PP_CompletionCallback ccb = task->ccb;
                if (ccb.func) {
                    ccb.func(ccb.user_data, task->result_to_pass);
                }

                // free task
                g_slice_free(struct message_loop_task_s, task);
                continue;   // run cycle again
            }
        } else if (teardown) {
            // teardown, no tasks in queue left
            break;
        }

        task = g_async_queue_timeout_pop(async_q, timeout);
        if (task)
            g_queue_insert_sorted(int_q, task, time_compare_func, NULL);
    }

    // mark thread as non-running
    ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP);
    if (ml) {
        if (increase_depth)
            ml->depth--;
        ml->running = 0;
        if (nested) {
            ml->running = saved_state.running;
            ml->teardown = saved_state.teardown;
        }
        pp_resource_release(message_loop);
    }
    pp_resource_unref(message_loop);
    if (destroy_ml)
        pp_resource_unref(message_loop);
    return PP_OK;
}

int32_t
ppb_message_loop_post_work_with_result(PP_Resource message_loop,
                                       struct PP_CompletionCallback callback, int64_t delay_ms,
                                       int32_t result_to_pass, int depth)
{
    if (callback.func == NULL) {
        trace_error("%s, callback.func == NULL\n", __func__);
        return PP_ERROR_BADARGUMENT;
    }

    struct pp_message_loop_s *ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP);
    if (!ml) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    if (ml->running && ml->teardown) {
        // message loop is in a teardown state
        pp_resource_release(message_loop);
        trace_error("%s, quit request received, no additional work could be posted\n", __func__);
        return PP_ERROR_FAILED;
    }

    struct message_loop_task_s *task = g_slice_alloc0(sizeof(*task));

    task->result_to_pass = result_to_pass;
    task->ccb = callback;
    task->depth = depth;

    // calculate absolute time callback should be run at
    clock_gettime(CLOCK_REALTIME, &task->when);
    task->when.tv_sec += delay_ms / 1000;
    task->when.tv_nsec += (delay_ms % 1000) * 1000 * 1000;
    while (task->when.tv_nsec >= 1000 * 1000 * 1000) {
        task->when.tv_sec += 1;
        task->when.tv_nsec -= 1000 * 1000 * 1000;
    }

    g_async_queue_push(ml->async_q, task);
    pp_resource_release(message_loop);
    return PP_OK;
}

int32_t
ppb_message_loop_post_work(PP_Resource message_loop, struct PP_CompletionCallback callback,
                           int64_t delay_ms)
{
    return ppb_message_loop_post_work_with_result(message_loop, callback, delay_ms, PP_OK, 0);
}

int32_t
ppb_message_loop_post_quit_depth(PP_Resource message_loop, PP_Bool should_destroy, int depth)
{
    struct pp_message_loop_s *ml = pp_resource_acquire(message_loop, PP_RESOURCE_MESSAGE_LOOP);
    if (!ml) {
        trace_error("%s, bad resource\n", __func__);
        return PP_ERROR_BADRESOURCE;
    }

    struct message_loop_task_s *task = g_slice_alloc0(sizeof(*task));

    task->terminate = 1;
    task->depth = depth;
    task->should_destroy_ml = should_destroy;
    task->result_to_pass = PP_OK;

    clock_gettime(CLOCK_REALTIME, &task->when); // run as early as possible

    g_async_queue_push(ml->async_q, task);
    pp_resource_release(message_loop);
    return PP_OK;
}

int32_t
ppb_message_loop_post_quit(PP_Resource message_loop, PP_Bool should_destroy)
{
    int depth = ppb_message_loop_get_depth(message_loop);
    return ppb_message_loop_post_quit_depth(message_loop, should_destroy, depth);
}
Esempio n. 19
0
static
void
url_loader_open_ptac(void *user_data)
{
    struct url_loader_open_param_s *p = user_data;
    struct pp_instance_s *pp_i = tables_get_pp_instance(p->instance_id);

    if (!pp_i) {
        p->retval = NPERR_INVALID_INSTANCE_ERROR;
        goto quit;
    }

    if (p->method == PP_METHOD_POST) {
        // POST request
        char   *tmpfname;
        int     fd;
        FILE   *fp = NULL;
        int     need_newline = 0;

        tmpfname = g_strdup_printf("/tmp/FreshPostBodyXXXXXX");    // TODO: make configurable

        fd = mkstemp(tmpfname);
        if (fd < 0) {
            p->retval = NPERR_GENERIC_ERROR;
            goto err;
        }

        fp = fdopen(fd, "wb+");
        if (!fp) {
            close(fd);
            p->retval = NPERR_GENERIC_ERROR;
            goto err;
        }

        if (p->request_headers) {
            fprintf(fp, "%s\n", p->request_headers);
            need_newline = 1;
        }
        if (p->custom_referrer_url) {
            // the header name should be "referer", that's how it's spelled in HTTP spec
            fprintf(fp, "Referer: %s\n", p->custom_referrer_url);
            need_newline = 1;
        }
        if (p->custom_content_transfer_encoding) {
            fprintf(fp, "Content-Transfer-Encoding: %s\n", p->custom_content_transfer_encoding);
            need_newline = 1;
        }
        if (p->custom_user_agent) {
            fprintf(fp, "User-Agent: %s\n", p->custom_user_agent);
            need_newline = 1;
        }

        if (p->post_data) {
            size_t post_len = post_data_get_all_item_length(p->post_data);

            if (post_len == (size_t)-1) {
                // PP_ERROR_FILECHANGED?
                goto err;
            }

            if (post_len > 0) {
                fprintf(fp, "Content-Length: %"PRIu64"\n", (uint64_t)post_len);
                need_newline = 1;
            }
        }

        if (need_newline)
            fprintf(fp, "\n");

        if (p->post_data) {
            for (guint k = 0; k < p->post_data->len; k ++)
                post_data_write_to_fp(p->post_data, k, fp);
        }

        fclose(fp); // flush all unwritten data and close the file
        fp = NULL;  // avoid calling fclose() twice

        if (p->target) {
            p->retval = npn.posturl(pp_i->npp, p->url, p->target, strlen(tmpfname), tmpfname, true);
        } else {
            p->retval = npn.posturlnotify(pp_i->npp, p->url, NULL, strlen(tmpfname), tmpfname, true,
                                          (void*)(size_t)p->loader);
        }
err:
        if (fp)
            fclose(fp);
        unlink(tmpfname);
        g_free(tmpfname);
    } else {
        // GET request
        if (p->target) {
            p->retval = npn.geturl(pp_i->npp, p->url, p->target);
        } else {
            p->retval = npn.geturlnotify(pp_i->npp, p->url, NULL, (void*)(size_t)p->loader);
        }
    }

quit:
    ppb_core_release_resource(p->loader);
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
Esempio n. 20
0
static
void
_url_loader_open_ptac(void *user_data)
{
    struct url_loader_open_param_s *p = user_data;
    struct pp_instance_s *pp_i = tables_get_pp_instance(p->instance_id);

    if (!pp_i) {
        p->retval = NPERR_INVALID_INSTANCE_ERROR;
        goto quit;
    }

    if (p->method == PP_METHOD_POST) {
        // POST request
        char   *tmpfname;
        int     fd;
        FILE   *fp;
        int     need_newline = 0;

        tmpfname = g_strdup_printf("/tmp/FreshPostBodyXXXXXX");    // TODO: make configurable

        fd = mkstemp(tmpfname);
        if (fd < 0) {
            p->retval = NPERR_GENERIC_ERROR;
            goto err;
        }

        fp = fdopen(fd, "wb+");
        if (!fp) {
            close(fd);
            p->retval = NPERR_GENERIC_ERROR;
            goto err;
        }

        if (p->request_headers) {
            fprintf(fp, "%s\n", p->request_headers);
            need_newline = 1;
        }
        if (p->custom_referrer_url) {
            fprintf(fp, "Referrer: %s\n", p->custom_referrer_url);
            need_newline = 1;
        }
        if (p->custom_content_transfer_encoding) {
            fprintf(fp, "Content-Transfer-Encoding: %s\n", p->custom_content_transfer_encoding);
            need_newline = 1;
        }
        if (p->custom_user_agent) {
            fprintf(fp, "User-Agent: %s\n", p->custom_user_agent);
            need_newline = 1;
        }
        if (p->post_len > 0) {
            fprintf(fp, "Content-Length: %"PRIu64"\n", (uint64_t)p->post_len);
            need_newline = 1;
        }

        if (need_newline)
            fprintf(fp, "\n");

        fwrite(p->post_data, 1, p->post_len, fp);
        fclose(fp);

        if (p->target) {
            p->retval = npn.posturl(pp_i->npp, p->url, p->target, strlen(tmpfname), tmpfname, true);
        } else {
            p->retval = npn.posturlnotify(pp_i->npp, p->url, NULL, strlen(tmpfname), tmpfname, true,
                                          (void*)(size_t)p->loader);
        }
err:
        unlink(tmpfname);
        g_free(tmpfname);
    } else {
        // GET request
        if (p->target) {
            p->retval = npn.geturl(pp_i->npp, p->url, p->target);
        } else {
            p->retval = npn.geturlnotify(pp_i->npp, p->url, NULL, (void*)(size_t)p->loader);
        }
    }

quit:
    ppb_message_loop_post_quit_depth(p->m_loop, PP_FALSE, p->depth);
}
Esempio n. 21
0
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);
}