Example #1
0
static void
data_buffer_stream_read_idle(void *user_data)
{
    rig_pb_stream_t *stream = user_data;
    int i;

    rut_poll_shell_remove_idle_FIXME(stream->shell, stream->buffer.read_idle);
    stream->buffer.read_idle = NULL;

    c_return_if_fail(stream->type == STREAM_TYPE_BUFFER);
    c_return_if_fail(stream->buffer.other_end != NULL);
    c_return_if_fail(stream->buffer.other_end->type == STREAM_TYPE_BUFFER);
    c_return_if_fail(stream->read_callback != NULL);

    for (i = 0; i < stream->buffer.incoming_write_closures->len; i++) {
        rig_pb_stream_write_closure_t *closure =
            c_array_index(stream->buffer.incoming_write_closures, void *, i);

        stream->read_callback(stream,
                              (uint8_t *)closure->buf.base,
                              closure->buf.len,
                              stream->read_data);

        /* Give the closure back so it can be freed */
        c_array_append_val(stream->buffer.other_end->buffer.finished_write_closures,
                           closure);
    }
    c_array_set_size(stream->buffer.incoming_write_closures, 0);

    drain_finished_write_closures(stream);
}
Example #2
0
void
rig_pb_stream_set_tcp_transport(rig_pb_stream_t *stream,
                                const char *hostname,
                                const char *port)
{
    uv_loop_t *loop = rut_uv_shell_get_loop(stream->shell);
    struct addrinfo hints;

    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);
    c_return_if_fail(stream->hostname == NULL);
    c_return_if_fail(stream->port == NULL);
    c_return_if_fail(stream->resolving == false);

    hints.ai_family = PF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = 0;

    stream->hostname = c_strdup(hostname);
    stream->port = c_strdup(port);

    rut_object_ref(stream); /* keep alive during resolve request */
    stream->resolving = true;
    uv_getaddrinfo(loop, &stream->resolver, on_address_resolved,
                   hostname, port, &hints);
}
Example #3
0
static void
_stream_free(void *object)
{
    rig_pb_stream_t *stream = object;

#ifdef USE_UV
    /* resolve and connect requests take a reference on the stream so
     * we should never try and free a stream in these cases... */
    c_return_if_fail(stream->resolving == false);
    c_return_if_fail(stream->connecting == false);
#endif

    rig_pb_stream_disconnect(stream);

    if (stream->type == STREAM_TYPE_BUFFER && stream->buffer.connect_idle) {
        rut_poll_shell_remove_idle_FIXME(stream->shell, stream->buffer.connect_idle);
        stream->buffer.connect_idle = NULL;
    }

    rut_closure_list_disconnect_all_FIXME(&stream->on_connect_closures);
    rut_closure_list_disconnect_all_FIXME(&stream->on_error_closures);

#ifdef USE_UV
    c_free(stream->hostname);
    c_free(stream->port);
#endif

    c_slice_free(rig_pb_stream_t, stream);
}
Example #4
0
void
_cg_indices_immutable_unref(cg_indices_t *indices)
{
    c_return_if_fail(cg_is_indices(indices));
    c_return_if_fail(indices->immutable_ref > 0);

    indices->immutable_ref--;
    _cg_buffer_immutable_unref(CG_BUFFER(indices->buffer));
}
Example #5
0
static void
objects_selection_event_cb(rig_objects_selection_t *selection,
                           rig_objects_selection_event_t event,
                           rut_object_t *object,
                           void *user_data)
{
    rig_selection_tool_t *tool = user_data;
    entity_state_t *entity_state;
    c_llist_t *l;

    if (!tool->active && event == RIG_OBJECTS_SELECTION_ADD_EVENT)
        return;

    if (rut_object_get_type(object) != &rig_entity_type)
        return;

    for (l = tool->selected_entities; l; l = l->next) {
        entity_state = l->data;
        if (entity_state->entity == object)
            break;
    }
    if (l == NULL)
        entity_state = NULL;

    switch (event) {
    case RIG_OBJECTS_SELECTION_ADD_EVENT: {
        c_return_if_fail(entity_state == NULL);

        entity_state = c_slice_new0(entity_state_t);
        entity_state->tool = tool;
        entity_state->entity = rut_object_ref(object);
        entity_state->control_points = NULL;

        tool->selected_entities =
            c_llist_prepend(tool->selected_entities, entity_state);

        entity_state->sizeable = find_sizeable_component(entity_state->entity);
        if (entity_state->sizeable)
            create_sizeable_control_points(entity_state);
        else
            create_dummy_control_points(entity_state);

        break;
    }

    case RIG_OBJECTS_SELECTION_REMOVE_EVENT:
        c_return_if_fail(entity_state != NULL);

        tool->selected_entities =
            c_llist_remove(tool->selected_entities, entity_state);
        entity_state_destroy(entity_state);
        break;
    }
}
Example #6
0
void
rig_pb_stream_accept_tcp_connection(rig_pb_stream_t *stream,
                                    uv_tcp_t *server)
{
    uv_loop_t *loop = rut_uv_shell_get_loop(stream->shell);
    struct sockaddr name;
    int namelen;
    int err;

    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);
    c_return_if_fail(stream->hostname == NULL);
    c_return_if_fail(stream->port == NULL);
    c_return_if_fail(stream->resolving == false);

    uv_tcp_init(loop, &stream->tcp.socket);
    stream->tcp.socket.data = stream;

    err = uv_accept((uv_stream_t *)server, (uv_stream_t *)&stream->tcp.socket);
    if (err != 0) {
        c_warning("Failed to accept tcp connection: %s", uv_strerror(err));
        uv_close((uv_handle_t *)&stream->tcp.socket, NULL);
        return;
    }

    err = uv_tcp_getpeername(&stream->tcp.socket, &name, &namelen);
    if (err != 0) {
        c_warning("Failed to query peer address of tcp socket: %s",
                  uv_strerror(err));

        stream->hostname = c_strdup("unknown");
        stream->port = c_strdup("0");
    } else if (name.sa_family != AF_INET) {
        c_warning("Accepted connection isn't ipv4");

        stream->hostname = c_strdup("unknown");
        stream->port = c_strdup("0");
    } else {
        struct sockaddr_in *addr = (struct sockaddr_in *)&name;
        char ip_address[17] = {'\0'};

        uv_ip4_name(addr, ip_address, 16);

        stream->hostname = c_strdup(ip_address);
        stream->port = c_strdup_printf("%u", ntohs(addr->sin_port));
    }

    stream->type = STREAM_TYPE_TCP;
    set_connected(stream);
}
Example #7
0
static void
on_connect(uv_connect_t *connection_request, int status)
{
    rig_pb_stream_t *stream = connection_request->data;

    c_return_if_fail(stream->connecting);

    stream->connecting = false;

    if (status < 0) {
        c_warning("Failed to connect to %s:%s - %s",
                  stream->hostname,
                  stream->port,
                  uv_strerror(status));

        rut_closure_list_invoke(&stream->on_error_closures,
                                rig_pb_stream_callback_t,
                                stream);
        goto exit;
    }

    stream->type = STREAM_TYPE_TCP;
    set_connected(stream);

exit:
    /* NB: we were at least keeping the stream alive while
     * waiting for the connection request to finish... */
    stream->connecting = false;
    rut_object_unref(stream);
}
Example #8
0
void
rut_mesh_foreach_index(rut_mesh_t *mesh,
                       rut_mesh_vertex_callback_t callback,
                       void *user_data,
                       const char *first_attribute,
                       ...)
{
    va_list ap;
    int n_attributes = 0;
    uint8_t **bases;
    int *strides;
    bool ready;

    va_start(ap, first_attribute);
    do {
        n_attributes++;
    } while (va_arg(ap, const char *));
    va_end(ap);

    bases = c_alloca(sizeof(void *) * n_attributes);
    strides = c_alloca(sizeof(int) * n_attributes);

    va_start(ap, first_attribute);
    ready = collect_attribute_state(mesh, bases, strides, first_attribute, ap);
    va_end(ap);

    c_return_if_fail(ready);

    foreach_vertex(
        mesh, callback, user_data, true, bases, strides, n_attributes);
}
Example #9
0
void
rig_pb_stream_set_in_thread_direct_transport(rig_pb_stream_t *stream,
                                             rig_pb_stream_t *other_end)
{
    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);

    stream->buffer.incoming_write_closures = c_array_new(false, /* nul terminated */
                                                         false, /* clear */
                                                         sizeof(void *));

    stream->buffer.finished_write_closures = c_array_new(false, /* nul terminated */
                                                         false, /* clear */
                                                         sizeof(void *));

    stream->buffer.other_end = other_end;

    /* Only consider the streams connected when both ends have been
     * initialised... */
    if (other_end->buffer.other_end == stream) {
        stream->type = STREAM_TYPE_BUFFER;
        other_end->type = STREAM_TYPE_BUFFER;

        queue_set_connected(stream);
        queue_set_connected(other_end);
    }
}
Example #10
0
void
_cg_egl_destroy_image(cg_device_t *dev, EGLImageKHR image)
{
    cg_renderer_egl_t *egl_renderer = dev->display->renderer->winsys;

    c_return_if_fail(egl_renderer->pf_eglDestroyImage);

    egl_renderer->pf_eglDestroyImage(egl_renderer->edpy, image);
}
Example #11
0
static void
queue_data_buffer_stream_read(rig_pb_stream_t *stream)
{
    c_return_if_fail(stream->buffer.other_end != NULL);
    c_return_if_fail(stream->buffer.other_end->type == STREAM_TYPE_BUFFER);
    c_return_if_fail(stream->buffer.incoming_write_closures->len);

    if (!stream->read_callback)
        return;

    if (stream->buffer.read_idle == NULL) {
        stream->buffer.read_idle =
            rut_poll_shell_add_idle_FIXME(stream->shell,
                                    data_buffer_stream_read_idle,
                                    stream,
                                    NULL); /* destroy */
    }
}
Example #12
0
void
c_get_current_time(c_timeval_t *result)
{
    struct timeval tv;

    c_return_if_fail(result != NULL);
    gettimeofday(&tv, NULL);
    result->tv_sec = tv.tv_sec;
    result->tv_usec = tv.tv_usec;
}
Example #13
0
void
cg_indices_set_offset(cg_indices_t *indices, size_t offset)
{
    c_return_if_fail(cg_is_indices(indices));

    if (C_UNLIKELY(indices->immutable_ref))
        warn_about_midscene_changes();

    indices->offset = offset;
}
Example #14
0
void
rig_selection_tool_update(rig_selection_tool_t *tool,
                          rut_object_t *paint_camera)
{
    c_return_if_fail(tool->active);

    if (!tool->selected_entities)
        return;

    update_control_point_positions(tool, paint_camera);
}
Example #15
0
void
rig_pb_stream_set_wslay_server_event_ctx(rig_pb_stream_t *stream,
                                         struct wslay_event_context *ctx)
{
    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);

    stream->type = STREAM_TYPE_WEBSOCKET_SERVER;
    stream->websocket_server.ctx = ctx;

    set_connected(stream);
}
Example #16
0
static void
queue_set_connected(rig_pb_stream_t *stream)
{
    c_return_if_fail(stream->buffer.connect_idle == NULL);

    stream->buffer.connect_idle =
        rut_poll_shell_add_idle_FIXME(stream->shell,
                                stream_set_connected_idle,
                                stream,
                                NULL); /* destroy */
}
Example #17
0
void
rig_pb_stream_set_in_worker(rig_pb_stream_t *stream, bool in_worker)
{
    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);

    stream->type = STREAM_TYPE_WORKER_IPC;
    stream->worker_ipc.in_worker = in_worker;

    _rig_worker_stream = stream;

    set_connected(stream);
}
Example #18
0
void
rig_pb_stream_set_read_callback(rig_pb_stream_t *stream,
                                void (*read_callback)(rig_pb_stream_t *stream,
                                                      const uint8_t *buf,
                                                      size_t len,
                                                      void *user_data),
                                void *user_data)
{
    stream->read_callback = read_callback;
    stream->read_data = user_data;

    switch (stream->type)
    {
#ifdef USE_UV
    case STREAM_TYPE_FD:
        uv_read_start((uv_stream_t *)&stream->fd.uv_fd_pipe,
                      read_buf_alloc_cb, read_cb);
        break;
    case STREAM_TYPE_TCP:
        uv_read_start((uv_stream_t *)&stream->tcp.socket,
                      read_buf_alloc_cb, read_cb);
        break;
    case STREAM_TYPE_WEBSOCKET_SERVER:
        break;
#endif
    case STREAM_TYPE_BUFFER:
        c_return_if_fail(stream->buffer.other_end != NULL);
        c_return_if_fail(stream->buffer.other_end->type == STREAM_TYPE_BUFFER);

        if (stream->buffer.incoming_write_closures->len)
            queue_data_buffer_stream_read(stream);
        break;
#ifdef __EMSCRIPTEN__
    case STREAM_TYPE_WORKER_IPC:
    case STREAM_TYPE_WEBSOCKET_CLIENT:
#endif
    case STREAM_TYPE_DISCONNECTED:
        break;
    }
}
Example #19
0
static void
_cg_winsys_destroy_gles2_context(cg_gles2_context_t *gles2_ctx)
{
    cg_device_t *dev = gles2_ctx->dev;
    cg_display_t *display = dev->display;
    cg_display_egl_t *egl_display = display->winsys;
    cg_renderer_t *renderer = display->renderer;
    cg_renderer_egl_t *egl_renderer = renderer->winsys;
    EGLContext egl_context = gles2_ctx->winsys;

    c_return_if_fail(egl_display->current_context != egl_context);

    eglDestroyContext(egl_renderer->edpy, egl_context);
}
Example #20
0
static void
on_address_resolved(uv_getaddrinfo_t *resolver,
                    int status,
                    struct addrinfo *result)
{
    rig_pb_stream_t *stream = rut_container_of(resolver, stream, resolver);
    uv_loop_t *loop = rut_uv_shell_get_loop(stream->shell);
    char ip_address[17] = {'\0'};

    c_return_if_fail(stream->resolving);

    if (status < 0) {
        c_warning("Failed to resolve slave address \"%s\": %s",
                  stream->hostname, uv_strerror(status));

        rut_closure_list_invoke(&stream->on_error_closures,
                                rig_pb_stream_callback_t,
                                stream);

        /* NB: we were at least keeping the stream alive while
         * waiting for the resolve request to finish... */
        stream->resolving = false;
        rut_object_unref(stream);

        return;
    }

    uv_ip4_name((struct sockaddr_in*)result->ai_addr, ip_address, 16);
    c_message("stream: Resolved address of \"%s\" = %s",
              stream->hostname, ip_address);

    uv_tcp_init(loop, &stream->tcp.socket);
    stream->tcp.socket.data = stream;

    /* NB: we took a reference to keep the stream alive while
     * resolving the address, so conceptually we are now handing
     * the reference over to keep the stream alive while waiting
     * for it to connect... */
    stream->resolving = false;
    stream->connecting = true;

    stream->connection_request.data = stream;
    uv_tcp_connect(&stream->connection_request,
                   &stream->tcp.socket,
                   result->ai_addr,
                   on_connect);

    uv_freeaddrinfo(result);
}
Example #21
0
void
rig_pb_stream_set_worker(rig_pb_stream_t *stream,
                         rig_worker_t worker)
{
    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);

    stream->type = STREAM_TYPE_WORKER_IPC;
    stream->worker_ipc.worker = worker;

    rig_emscripten_worker_set_main_onmessage(worker,
                                             rig_pb_stream_main_onmessage,
                                             stream);

    set_connected(stream);
}
Example #22
0
static void
slave__test(Rig__Slave_Service *service,
            const Rig__Query *query,
            Rig__TestResult_Closure closure,
            void *closure_data)
{
    Rig__TestResult result = RIG__TEST_RESULT__INIT;
    // rig_slave_t *slave = rig_pb_rpc_closure_get_connection_data
    // (closure_data);

    c_return_if_fail(query != NULL);

    c_debug("Test Query\n");

    closure(&result, closure_data);
}
Example #23
0
void
rut_fold_set_header_child(rut_fold_t *fold, rut_object_t *child)
{
    c_return_if_fail(rut_object_get_type(fold) == &rut_fold_type);

    if (child)
        rut_object_claim(child, fold);

    if (fold->header_child) {
        rut_box_layout_remove(fold->header_hbox_right, fold->header_child);
        rut_object_release(fold->header_child, fold);
    }

    fold->header_child = child;
    rut_box_layout_add(fold->header_hbox_right, true, child);
}
Example #24
0
static void
_cg_winsys_display_destroy(cg_display_t *display)
{
    cg_renderer_egl_t *egl_renderer = display->renderer->winsys;
    cg_display_egl_t *egl_display = display->winsys;

    c_return_if_fail(egl_display != NULL);

    cleanup_device(display);

    if (egl_renderer->platform_vtable->display_destroy)
        egl_renderer->platform_vtable->display_destroy(display);

    c_slice_free(cg_display_egl_t, display->winsys);
    display->winsys = NULL;
}
Example #25
0
static void
_cg_winsys_display_destroy(cg_display_t *display)
{
    cg_display_sdl2_t *sdl_display = display->winsys;

    c_return_if_fail(sdl_display != NULL);

    if (sdl_display->context)
        SDL_GL_DeleteContext(sdl_display->context);

    if (sdl_display->dummy_window)
        SDL_DestroyWindow(sdl_display->dummy_window);

    c_slice_free(cg_display_sdl2_t, display->winsys);
    display->winsys = NULL;
}
Example #26
0
void
rig_pb_stream_set_fd_transport(rig_pb_stream_t *stream, int fd)
{
    uv_loop_t *loop = rut_uv_shell_get_loop(stream->shell);

    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);

    stream->type = STREAM_TYPE_FD;

    uv_pipe_init(loop, &stream->fd.uv_fd_pipe, true /* enable handle passing */);
    stream->fd.uv_fd_pipe.data = stream;

    uv_pipe_open(&stream->fd.uv_fd_pipe, fd);

    set_connected(stream);
}
Example #27
0
void
rut_fold_set_child(rut_fold_t *fold, rut_object_t *child)
{
    c_return_if_fail(rut_object_get_type(fold) == &rut_fold_type);

    if (child)
        rut_object_claim(child, fold);

    if (fold->child) {
        if (!fold->folded)
            rut_box_layout_remove(fold->vbox, fold->child);
        rut_object_release(fold->child, fold);
    }

    fold->child = child;
    if (child && !fold->folded)
        rut_box_layout_add(fold->vbox, true, child);
}
Example #28
0
static void
_cg_winsys_display_destroy(cg_display_t *display)
{
    cg_webgl_display_t *webgl_display = display->winsys;

    c_return_if_fail(webgl_display != NULL);

    if (webgl_display->context > 0)
        emscripten_webgl_destroy_context(webgl_display->context);

    if (webgl_display->window > 0)
        CGlib_Emscripten_DestroyWindow(webgl_display->window);

    c_free(webgl_display->window_id);

    c_slice_free(cg_webgl_display_t, display->winsys);
    display->winsys = NULL;
}
Example #29
0
void
rig_pb_stream_set_websocket_client_fd(rig_pb_stream_t *stream,
                                      int fd)
{
    c_return_if_fail(stream->type == STREAM_TYPE_DISCONNECTED);

    stream->type = STREAM_TYPE_WEBSOCKET_CLIENT;
    stream->websocket_client.socket = fd;

#warning "FIXME: support multiple websocket based streams"
    /* XXX: These are global callbacks and so is the user data
     * so we need some way to lookup a stream based on a
     * socket fd within the callbacks */
    emscripten_set_socket_error_callback(stream /* user data */,
                                         rig_pb_stream_websocket_error_cb);
    emscripten_set_socket_open_callback(stream /* user data */,
                                        rig_pb_stream_websocket_ready_cb);
    emscripten_set_socket_message_callback(stream /* user data */,
                                           rig_pb_stream_websocket_ready_cb);

    set_connected(stream);
}
Example #30
0
void
rig_pb_stream_write(rig_pb_stream_t *stream,
                    rig_pb_stream_write_closure_t *closure)
{
    c_return_if_fail(stream->type != STREAM_TYPE_DISCONNECTED);

    switch (stream->type) {
    case STREAM_TYPE_BUFFER: {
        c_return_if_fail(stream->buffer.other_end != NULL);
        c_return_if_fail(stream->buffer.other_end->type == STREAM_TYPE_BUFFER);

        c_array_append_val(stream->buffer.other_end->buffer.incoming_write_closures, closure);

        queue_data_buffer_stream_read(stream->buffer.other_end);

        break;
    }

#ifdef USE_UV
    case STREAM_TYPE_FD:
    case STREAM_TYPE_TCP: {
        closure->write_req.data = closure;

        uv_write(&closure->write_req,
                 (uv_stream_t *)&stream->fd.uv_fd_pipe,
                 &closure->buf,
                 1, /* n buffers */
                 uv_write_done_cb);
        break;
    }
    case STREAM_TYPE_WEBSOCKET_SERVER: {
        struct wslay_event_fragmented_msg arg;

        memset(&arg, 0, sizeof(arg));
        arg.opcode = WSLAY_BINARY_FRAME;
        arg.source.data = closure;
        arg.read_callback = fragmented_wslay_read_cb;

        closure->current_offset = 0;

        wslay_event_queue_fragmented_msg(stream->websocket_server.ctx, &arg);
        wslay_event_send(stream->websocket_server.ctx);
        break;
    }
#endif

#ifdef __EMSCRIPTEN__
    case STREAM_TYPE_WORKER_IPC:
        if (stream->worker_ipc.in_worker)
            rig_emscripten_worker_post_to_main(closure->buf.base,
                                               closure->buf.len);
        else
            rig_emscripten_worker_post(stream->worker_ipc.worker,
                                       "rig_pb_stream_worker_onmessage",
                                       closure->buf.base,
                                       closure->buf.len);

        closure->done_callback(closure);
        break;

    case STREAM_TYPE_WEBSOCKET_CLIENT:
        c_debug("stream: websocket send() %d bytes", closure->buf.len);
        send(stream->websocket_client.socket,
             closure->buf.base,
             closure->buf.len,
             0 /* flags */);

        closure->done_callback(closure);
        break;
#endif

    case STREAM_TYPE_DISCONNECTED:
        c_warn_if_reached();
        break;
    }
}