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); }
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); }
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); }
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)); }
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; } }
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); }
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); }
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); }
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); } }
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); }
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 */ } }
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; }
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; }
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); }
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); }
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 */ }
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); }
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; } }
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); }
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); }
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); }
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); }
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); }
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; }
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; }
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); }
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); }
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; }
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); }
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; } }