<commit_before>/*
 * Copyright © 2013-2014  <NAME>
 *
 * This file is part of FreshPlayerPlugin.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <assert.h>
#include <inttypes.h>
#include <npapi/npapi.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xinerama.h>
#include <pthread.h>
#include "trace.h"
#include "reverse_constant.h"
#include "pp_interface.h"
#include "pp_resource.h"
#include "tables.h"
#include "p2n_proxy_class.h"
#include <ppapi/c/ppp_instance.h>
#include <ppapi/c/ppp_input_event.h>
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/private/ppp_instance_private.h>
#include "ppb_input_event.h"
#include "ppb_url_loader.h"
#include "ppb_var.h"
#include "ppb_core.h"
#include "header_parser.h"
#include "keycodeconvert.h"


static
PP_Instance
generate_new_pp_instance_id(void)
{
    static int32_t instance_id = 10;
    static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

    pthread_mutex_lock(&m);
    int32_t result = instance_id++;
    pthread_mutex_unlock(&m);

    return result;
}

NPError
NPP_New(NPMIMEType pluginType, NPP npp, uint16_t mode, int16_t argc, char *argn[],
        char *argv[], NPSavedData *saved)
{
    // TODO: mode parameter handling
    int k;
    struct pp_instance_s *pp_i;
    trace_info("[NPP] {part} %s pluginType=%s npp=%p, mode=%d, argc=%d, saved=%p\n", __func__,
               pluginType, npp, mode, argc, saved);

    tables_add_npp_instance(npp);
    np_main_thread = pthread_self();

    for (k = 0; k < argc; k ++)
        trace_info("            argn[%d] = %s, argv[%d] = %s\n", k, argn[k], k, argv[k]);

    pp_i = calloc(sizeof(*pp_i), 1);
    npp->pdata = pp_i;
    if (!pp_i)
        return NPERR_OUT_OF_MEMORY_ERROR;

    pp_i->npp = npp;
    pp_i->ppp_instance_1_1 = ppp_get_interface(PPP_INSTANCE_INTERFACE_1_1);
    if (!pp_i->ppp_instance_1_1)
        return NPERR_GENERIC_ERROR;
    pp_i->ppp_input_event = ppp_get_interface(PPP_INPUT_EVENT_INTERFACE_0_1);

    pp_i->argc = argc;
    pp_i->argn = malloc(argc * sizeof(char*));
    pp_i->argv = malloc(argc * sizeof(char*));
    for (k = 0; k < argc; k ++) {
        pp_i->argn[k] = strdup(argn[k] ? argn[k] : "");
        pp_i->argv[k] = strdup(argv[k] ? argv[k] : "");

        if (strcasecmp(argn[k], "src") == 0) {
            pp_i->instance_url = strdup(argv[k]);
        }
    }

    pp_i->is_fullframe = (mode == NP_FULL);
    pp_i->pp_instance_id = generate_new_pp_instance_id();
    tables_add_pp_instance(pp_i->pp_instance_id, pp_i);

    pthread_mutex_init(&pp_i->lock, NULL);
    pp_i->dpy = XOpenDisplay(NULL);
    if (!pp_i->dpy) {
        trace_error("%s, can't open X Display\n", __func__);
    }

    // get fullscreen resolution
    int screen_count;
    pthread_mutex_lock(&pp_i->lock);
    XineramaScreenInfo *xsi = XineramaQueryScreens(pp_i->dpy, &screen_count);
    XWindowAttributes xw_attrs;
    if (xsi) {
        int screen = config.xinerama_screen;
        if (screen < 0)
            screen = 0;
        if (screen > screen_count - 1)
            screen = screen_count - 1;
        pp_i->fs_width =  xsi[screen].width;
        pp_i->fs_height = xsi[screen].height;
        XFree(xsi);
    } else if (XGetWindowAttributes(pp_i->dpy, DefaultRootWindow(pp_i->dpy), &xw_attrs)) {
        pp_i->fs_width =  xw_attrs.width;
        pp_i->fs_height = xw_attrs.height;
    } else {
        pp_i->fs_width = 100;
        pp_i->fs_height = 100;
    }
    pthread_mutex_unlock(&pp_i->lock);

    // request windowless operation
    npn.setvalue(npp, NPPVpluginWindowBool, (void*)0);

    pp_i->ppp_instance_1_1->DidCreate(pp_i->pp_instance_id, pp_i->argc, pp_i->argn, pp_i->argv);
    pp_i->instance_loaded = 1;

    return NPERR_NO_ERROR;
}

NPError
NPP_Destroy(NPP npp, NPSavedData **save)
{
    trace_info("[NPP] {full} %s npp=%p, save=%p\n", __func__, npp, save);
    tables_remove_npp_instance(npp);
    struct pp_instance_s *pp_i = npp->pdata;
    pp_i->ppp_instance_1_1->DidDestroy(pp_i->pp_instance_id);<commit_msg>add HandleDocumentLoad call for fullframe instances<commit_after>/*
 * Copyright © 2013-2014  <NAME>
 *
 * This file is part of FreshPlayerPlugin.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <assert.h>
#include <inttypes.h>
#include <npapi/npapi.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xinerama.h>
#include <pthread.h>
#include "trace.h"
#include "reverse_constant.h"
#include "pp_interface.h"
#include "pp_resource.h"
#include "tables.h"
#include "p2n_proxy_class.h"
#include <ppapi/c/ppp_instance.h>
#include <ppapi/c/ppp_input_event.h>
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/private/ppp_instance_private.h>
#include "ppb_input_event.h"
#include "ppb_url_loader.h"
#include "ppb_url_request_info.h"
#include "ppb_var.h"
#include "ppb_core.h"
#include "header_parser.h"
#include "keycodeconvert.h"


static
PP_Instance
generate_new_pp_instance_id(void)
{
    static int32_t instance_id = 10;
    static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

    pthread_mutex_lock(&m);
    int32_t result = instance_id++;
    pthread_mutex_unlock(&m);

    return result;
}

static
void
empty_completion_callback(void *user_data, int32_t result)
{
    (void)user_data;
    (void)result;
}

NPError
NPP_New(NPMIMEType pluginType, NPP npp, uint16_t mode, int16_t argc, char *argn[],
        char *argv[], NPSavedData *saved)
{
    // TODO: mode parameter handling
    int k;
    struct pp_instance_s *pp_i;
    trace_info("[NPP] {part} %s pluginType=%s npp=%p, mode=%d, argc=%d, saved=%p\n", __func__,
               pluginType, npp, mode, argc, saved);

    tables_add_npp_instance(npp);
    np_main_thread = pthread_self();

    for (k = 0; k < argc; k ++)
        trace_info("            argn[%d] = %s, argv[%d] = %s\n", k, argn[k], k, argv[k]);

    pp_i = calloc(sizeof(*pp_i), 1);
    npp->pdata = pp_i;
    if (!pp_i)
        return NPERR_OUT_OF_MEMORY_ERROR;

    pp_i->npp = npp;
    pp_i->ppp_instance_1_1 = ppp_get_interface(PPP_INSTANCE_INTERFACE_1_1);
    if (!pp_i->ppp_instance_1_1)
        return NPERR_GENERIC_ERROR;
    pp_i->ppp_input_event = ppp_get_interface(PPP_INPUT_EVENT_INTERFACE_0_1);

    pp_i->argc = argc;
    pp_i->argn = malloc(argc * sizeof(char*));
    pp_i->argv = malloc(argc * sizeof(char*));
    for (k = 0; k < argc; k ++) {
        pp_i->argn[k] = strdup(argn[k] ? argn[k] : "");
        pp_i->argv[k] = strdup(argv[k] ? argv[k] : "");

        if (strcasecmp(argn[k], "src") == 0) {
            pp_i->instance_url = strdup(argv[k]);
        }
    }

    pp_i->is_fullframe = (mode == NP_FULL);
    pp_i->pp_instance_id = generate_new_pp_instance_id();
    tables_add_pp_instance(pp_i->pp_instance_id, pp_i);

    pthread_mutex_init(&pp_i->lock, NULL);
    pp_i->dpy = XOpenDisplay(NULL);
    if (!pp_i->dpy) {
        trace_error("%s, can't open X Display\n", __func__);
    }

    // get fullscreen resolution
    int screen_count;
    pthread_mutex_lock(&pp_i->lock);
    XineramaScreenInfo *xsi = XineramaQueryScreens(pp_i->dpy, &screen_count);
    XWindowAttributes xw_attrs;
    if (xsi) {
        int screen = config.xinerama_screen;
        if (screen < 0)
            screen = 0;
        if (screen > screen_count - 1)
            screen = screen_count - 1;
        pp_i->fs_width =  xsi[screen].width;
        pp_i->fs_height = xsi[screen].height;
        XFree(xsi);
    } else if (XGetWindowAttributes(pp_i->dpy, DefaultRootWindow(pp_i->dpy), &xw_attrs)) {
        pp_i->fs_width =  xw_attrs.width;
        pp_i->fs_height = xw_attrs.height;
    } else {
        pp_i->fs_width = 100;
        pp_i->fs_height = 100;
    }
    pthread_mutex_unlock(&pp_i->lock);

    // request windowless operation
    npn.setvalue(npp, NPPVpluginWindowBool, (void*)0);

    pp_i->ppp_instance_1_1->DidCreate(pp_i->pp_instance_id, pp_i->argc, pp_i->argn, pp_i->argv);
    pp_i->instance_loaded = 1;

    if (mode == NP_FULL) {
        PP_Resource request_info = ppb_url_request_info_create(pp_i->pp_instance_id);
        PP_Resource url_loader = ppb_url_loader_create(pp_i->pp_instance_id);

        struct PP_Var s_url = PP_MakeString(pp_i->instance_url);
        struct PP_Var s_method = PP_MakeString("GET");

        ppb_url_request_info_set_property(request_info, PP_URLREQUESTPROPERTY_URL, s_url);
        ppb_url_request_info_set_property(request_info, PP_URLREQUESTPROPERTY_METHOD, s_method);
        ppb_url_loader_open(url_loader, request_info,
                            PP_MakeCompletionCallback(empty_completion_callback, NULL));
        ppb_var_release(s_url);
        ppb_var_release(s_method);
        ppb_core_release_resource(request_info);

        pp_i->ppp_instance_1_1->HandleDocumentLoad(pp_i->pp_instance_id, url_loader);
    }

    return NPERR_NO_ERROR;
}

NPError
NPP_Destroy(NPP npp, NPSavedData **save)
{
    trace_info("[NPP] {full} %s npp=%p, save=%p\n", __func__, npp, save);
    tables_remove_npp_instance(npp);
    struct pp_instance_s *pp_i = npp->pdata;
    pp_i->ppp_instance_1_1->DidDestroy(pp_i->pp_instance_id);
{'fraction_non_alphanumeric': 0.12177586051945717, 'fraction_numerical': 0.0095263772804889, 'mean_word_length': 3.6424697538589905, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6393645', 'n_tokens_mistral': 4136, 'n_tokens_neox': 4023, 'n_words': 928}