static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size) { SpiceVmcState *state; state = SPICE_CONTAINEROF(rcc->channel, SpiceVmcState, channel); switch (type) { case SPICE_MSGC_SPICEVMC_DATA: assert(!state->recv_from_client_buf); state->recv_from_client_buf = spice_char_device_write_buffer_get(state->chardev_st, rcc->client, size); if (!state->recv_from_client_buf) { spice_error("failed to allocate write buffer"); return NULL; } return state->recv_from_client_buf->buf; default: return spice_malloc(size); } }
static void smartcard_init(void) { ChannelCbs channel_cbs = { NULL, }; ClientCbs client_cbs = { NULL, }; uint32_t migration_flags = SPICE_MIGRATE_NEED_FLUSH | SPICE_MIGRATE_NEED_DATA_TRANSFER; spice_assert(!g_smartcard_channel); channel_cbs.config_socket = smartcard_channel_client_config_socket; channel_cbs.on_disconnect = smartcard_channel_on_disconnect; channel_cbs.send_item = smartcard_channel_send_item; channel_cbs.hold_item = smartcard_channel_hold_pipe_item; channel_cbs.release_item = smartcard_channel_release_pipe_item; channel_cbs.alloc_recv_buf = smartcard_channel_alloc_msg_rcv_buf; channel_cbs.release_recv_buf = smartcard_channel_release_msg_rcv_buf; channel_cbs.handle_migrate_flush_mark = smartcard_channel_client_handle_migrate_flush_mark; channel_cbs.handle_migrate_data = smartcard_channel_client_handle_migrate_data; g_smartcard_channel = (SmartCardChannel*)red_channel_create(sizeof(SmartCardChannel), core, SPICE_CHANNEL_SMARTCARD, 0, FALSE /* handle_acks */, smartcard_channel_handle_message, &channel_cbs, migration_flags); if (!g_smartcard_channel) { spice_error("failed to allocate Smartcard Channel"); } client_cbs.connect = smartcard_connect_client; red_channel_register_client_cbs(&g_smartcard_channel->base, &client_cbs); reds_register_channel(&g_smartcard_channel->base); }
static inline pixman_image_t *__surface_create_stride(pixman_format_code_t format, int width, int height, int stride) { uint8_t *data; uint8_t *stride_data; pixman_image_t *surface; PixmanData *pixman_data; data = (uint8_t *)spice_malloc_n(abs(stride), height); if (stride < 0) { stride_data = data + (-stride) * (height - 1); } else { stride_data = data; } surface = pixman_image_create_bits(format, width, height, (uint32_t *)stride_data, stride); if (surface == NULL) { free(data); spice_error("create surface failed, out of memory"); } pixman_data = pixman_image_add_data(surface); pixman_data->data = data; pixman_data->format = format; return surface; }
static void spicevmc_red_channel_send_item(RedChannelClient *rcc, PipeItem *item) { SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); switch (item->type) { case PIPE_ITEM_TYPE_SPICEVMC_DATA: spicevmc_red_channel_send_data(rcc, m, item); break; case PIPE_ITEM_TYPE_SPICEVMC_MIGRATE_DATA: spicevmc_red_channel_send_migrate_data(rcc, m, item); break; case PIPE_ITEM_TYPE_PORT_INIT: spicevmc_red_channel_send_port_init(rcc, m, item); break; case PIPE_ITEM_TYPE_PORT_EVENT: spicevmc_red_channel_send_port_event(rcc, m, item); break; default: spice_error("bad pipe item %d", item->type); free(item); return; } red_channel_client_begin_send_message(rcc); }
static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size) { SmartCardChannelClient *scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base); /* todo: only one reader is actually supported. When we fix the code to support * multiple readers, we will porbably associate different devices to * differenc channels */ if (!scc->smartcard_state) { scc->msg_in_write_buf = FALSE; return spice_malloc(size); } else { SmartCardDeviceState *st; spice_assert(g_smartcard_readers.num == 1); st = scc->smartcard_state; spice_assert(st->scc || scc->smartcard_state); spice_assert(!scc->write_buf); scc->write_buf = spice_char_device_write_buffer_get(st->chardev_st, rcc->client, size); if (!scc->write_buf) { spice_error("failed to allocate write buffer"); return NULL; } scc->msg_in_write_buf = TRUE; return scc->write_buf->buf; } }
static void cursor_channel_send_item(RedChannelClient *rcc, PipeItem *pipe_item) { SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); CursorChannelClient *ccc = RCC_TO_CCC(rcc); switch (pipe_item->type) { case PIPE_ITEM_TYPE_CURSOR: cursor_marshall(rcc, m, SPICE_CONTAINEROF(pipe_item, CursorPipeItem, base)); break; case PIPE_ITEM_TYPE_INVAL_ONE: red_marshall_inval(rcc, m, (CacheItem *)pipe_item); break; case PIPE_ITEM_TYPE_VERB: red_marshall_verb(rcc, (VerbItem*)pipe_item); break; case PIPE_ITEM_TYPE_CURSOR_INIT: red_reset_cursor_cache(rcc); red_marshall_cursor_init(rcc, m, pipe_item); break; case PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE: red_reset_cursor_cache(rcc); red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INVAL_ALL, NULL); break; default: spice_error("invalid pipe item type"); } cursor_channel_client_release_item_before_push(ccc, pipe_item); red_channel_client_begin_send_message(rcc); }
static VALUE kclear(VALUE self) { kclear_c(); if(spice_error(SPICE_ERROR_SHORT)) return Qfalse; return Qtrue; }
VALUE kclear(VALUE self) { kclear_c(); if(spice_error(SHORT)) return Qfalse; return Qtrue; }
static VALUE str2et(VALUE self, VALUE epoch) { double ephemeris_time; str2et_c(StringValuePtr(epoch), &ephemeris_time); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; return DBL2NUM(ephemeris_time); }
static VALUE pgrrec(VALUE self, VALUE body, VALUE longitude, VALUE latitude, VALUE altitude, VALUE radius_equatorial, VALUE flattening) { double vector[3]; pgrrec_c(RB_SYM2STR(body), NUM2DBL(radius_equatorial), NUM2DBL(flattening), NUM2DBL(longitude), NUM2DBL(latitude), NUM2DBL(altitude), vector); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; return rb_nmatrix_dense_create(FLOAT64, (size_t *) VECTOR_SHAPE, 2, (void *) vector, 3); }
/* SpiceDouble phaseq_c ( SpiceDouble et, ConstSpiceChar * target, ConstSpiceChar * illmn, ConstSpiceChar * obsrvr, ConstSpiceChar * abcorr ) */ static VALUE phaseq(VALUE self, VALUE et, VALUE target, VALUE illmn, VALUE obsrvr, VALUE abcorr) { double phase_angle; phase_angle = phaseq_c(NUM2DBL(et), RB_SYM2STR(target), RB_SYM2STR(illmn), RB_SYM2STR(obsrvr), RB_SYM2STR(abcorr)); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; return DBL2NUM(phase_angle); }
int main(int argc, char *argv[]) { RedsStream *st[2]; int sv[2]; int ret, fd = -1; char c; spice_return_val_if_fail(server_init() == 0, -1); if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) { spice_error("socketpair failed %s", strerror(errno)); return -1; } st[0] = reds_stream_new(server, sv[0]); spice_assert(reds_stream_is_plain_unix(st[0])); st[1] = reds_stream_new(server, sv[1]); spice_assert(reds_stream_is_plain_unix(st[1])); /* send stdin, for the fun of it */ ret = reds_stream_send_msgfd(st[0], 0); spice_assert(ret == 1); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd != -1); close(fd); /* send invalid fd behaviour */ ret = reds_stream_send_msgfd(st[0], -1); spice_assert(ret == 1); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd == -1); /* batch test */ ret = reds_stream_send_msgfd(st[0], 0); spice_assert(ret == 1); ret = reds_stream_send_msgfd(st[0], 0); spice_assert(ret == 1); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd != -1); close(fd); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd != -1); close(fd); reds_stream_free(st[0]); reds_stream_free(st[1]); return 0; }
//TODO : Test this, current kernel files do not cover this static VALUE lspcn(int argc, VALUE *argv, VALUE self) { double result; result = lspcn_c(RB_SYM2STR(argv[0]), NUM2DBL(argv[1]), RB_SYM2STR(argv[2])); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; return DBL2NUM(result); }
static pixman_image_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id) { ImageCache *cache = SPICE_UPCAST(ImageCache, spice_cache); ImageCacheItem *item = image_cache_find(cache, id); if (!item) { spice_error("not found"); } return pixman_image_ref(item->image); }
static VALUE unload(VALUE self, VALUE kernel) { sigset_t old_mask = block_signals(); unload_c(StringValuePtr(kernel)); restore_signals(old_mask); if(spice_error(SPICE_ERROR_SHORT)) return Qfalse; return Qtrue; }
VALUE furnsh(int argc, VALUE *argv, VALUE self) { sigset_t old_mask = block_signals(); furnsh_c(StringValuePtr(argv[0])); restore_signals(old_mask); if(spice_error(SHORT)) return Qfalse; return Qtrue; }
static VALUE recpgr(VALUE self, VALUE body, VALUE rectangular, VALUE radius_equatorial, VALUE flattening) { double longitude, latitude, altitude; recpgr_c(RB_SYM2STR(body), NM_STORAGE_DENSE(rectangular)->elements, NUM2DBL(radius_equatorial), NUM2DBL(flattening), &longitude, &latitude, &altitude); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; return rb_ary_new3(3, DBL2NUM(longitude), DBL2NUM(latitude), DBL2NUM(altitude)); }
static int smartcard_channel_client_handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message) { SmartCardChannelClient *scc; SpiceMigrateDataHeader *header; SpiceMigrateDataSmartcard *mig_data; scc = SPICE_CONTAINEROF(rcc, SmartCardChannelClient, base); header = (SpiceMigrateDataHeader *)message; mig_data = (SpiceMigrateDataSmartcard *)(header + 1); if (size < sizeof(SpiceMigrateDataHeader) + sizeof(SpiceMigrateDataSmartcard)) { spice_error("bad message size"); return FALSE; } if (!migration_protocol_validate_header(header, SPICE_MIGRATE_DATA_SMARTCARD_MAGIC, SPICE_MIGRATE_DATA_SMARTCARD_VERSION)) { spice_error("bad header"); return FALSE; } if (!mig_data->base.connected) { /* client wasn't attached to a smartcard */ return TRUE; } if (!scc->smartcard_state) { SpiceCharDeviceInstance *char_device = smartcard_readers_get_unattached(); if (!char_device) { spice_warning("no unattached device available"); return TRUE; } else { smartcard_char_device_attach_client(char_device, scc); } } spice_debug("reader added %d partial read_size %u", mig_data->reader_added, mig_data->read_size); scc->smartcard_state->reader_added = mig_data->reader_added; smartcard_device_state_restore_partial_read(scc->smartcard_state, mig_data); return spice_char_device_state_restore(scc->smartcard_state->chardev_st, &mig_data->base); }
static VALUE ktotal(int argc, VALUE *argv, VALUE self) { SpiceInt kernel_count; if(argc == 0) ktotal_c("ALL", &kernel_count); //Else convert Symbol to ID, ID to string if category argument supplied else ktotal_c(RB_SYM2STR(argv[0]), &kernel_count); spice_error(SPICE_ERROR_SHORT); return INT2FIX(kernel_count); }
VALUE ktotal(int argc, VALUE *argv, VALUE self) { SpiceInt kernel_count; if(argc == 0) ktotal_c("ALL", &kernel_count); //Else convert Symbol to ID, ID to string if category argument supplied else ktotal_c(rb_id2name(SYM2ID(argv[0])), &kernel_count); spice_error(SHORT); return INT2FIX(kernel_count); }
static void cursor_marshall(RedChannelClient *rcc, SpiceMarshaller *m, CursorPipeItem *cursor_pipe_item) { CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base); CursorChannelClient *ccc = RCC_TO_CCC(rcc); CursorItem *item = cursor_pipe_item->cursor_item; PipeItem *pipe_item = &cursor_pipe_item->base; RedCursorCmd *cmd; spice_return_if_fail(cursor_channel); cmd = item->red_cursor; switch (cmd->type) { case QXL_CURSOR_MOVE: { SpiceMsgCursorMove cursor_move; red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_MOVE, pipe_item); cursor_move.position = cmd->u.position; spice_marshall_msg_cursor_move(m, &cursor_move); break; } case QXL_CURSOR_SET: { SpiceMsgCursorSet cursor_set; AddBufInfo info; red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_SET, pipe_item); cursor_set.position = cmd->u.set.position; cursor_set.visible = cursor_channel->cursor_visible; cursor_fill(ccc, &cursor_set.cursor, item, &info); spice_marshall_msg_cursor_set(m, &cursor_set); add_buf_from_info(m, &info); break; } case QXL_CURSOR_HIDE: red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_HIDE, pipe_item); break; case QXL_CURSOR_TRAIL: { SpiceMsgCursorTrail cursor_trail; red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_TRAIL, pipe_item); cursor_trail.length = cmd->u.trail.length; cursor_trail.frequency = cmd->u.trail.frequency; spice_marshall_msg_cursor_trail(m, &cursor_trail); } break; default: spice_error("bad cursor command %d", cmd->type); } }
static VALUE getfov(VALUE self, VALUE instid, VALUE room, VALUE shapelen, VALUE framelen) { int count, vector_count; //Maximum size of SPICE ID is 32 chars char * shape = ALLOC_N(char, shapelen); char * frame = ALLOC_N(char, framelen); //Upper bound on boundary vectors is uncertain double boundary_sight[3]; double boundary_vectors [10][3]; VALUE rb_bounds; VALUE rb_sight_vector = rb_ary_new(); VALUE rb_shape, rb_frame; getfov_c(FIX2INT(instid), FIX2INT(room), FIX2INT(shapelen), FIX2INT(framelen), shape, frame, boundary_sight, &vector_count, boundary_vectors); if(spice_error(SPICE_ERROR_SHORT)) { return Qnil; } rb_sight_vector = rb_nmatrix_dense_create(FLOAT64, (size_t *) VECTOR_SHAPE, 2, (void *) boundary_sight, 3); rb_bounds = rb_ary_new2(vector_count); for (count = 0; count < vector_count; count++) { rb_ary_push(rb_bounds, rb_nmatrix_dense_create(FLOAT64, (size_t *) VECTOR_SHAPE, 2, (void *) boundary_vectors[count], 3)); } rb_shape = RB_STR2SYM(shape); rb_frame = RB_STR2SYM(frame); xfree(shape); xfree(frame); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; return rb_ary_new3(5, rb_shape, rb_frame, rb_sight_vector, rb_bounds, INT2FIX(vector_count)); }
static void smartcard_char_device_notify_reader_add(SmartCardDeviceState *st) { SpiceCharDeviceWriteBuffer *write_buf; VSCMsgHeader *vheader; write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(vheader)); if (!write_buf) { spice_error("failed to allocate write buffer"); return; } st->reader_added = TRUE; vheader = (VSCMsgHeader *)write_buf->buf; vheader->type = VSC_ReaderAdd; vheader->reader_id = st->reader_id; vheader->length = 0; smartcard_channel_write_to_reader(write_buf); }
static PixmanData * pixman_image_add_data(pixman_image_t *image) { PixmanData *data; data = (PixmanData *)pixman_image_get_destroy_data(image); if (data == NULL) { data = (PixmanData *)calloc(1, sizeof(PixmanData)); if (data == NULL) { spice_error("out of memory"); } pixman_image_set_destroy_function(image, release_data, data); } return data; }
// TODO: share code between before/after_push since most of the items need the same // release static void cursor_channel_client_release_item_before_push(CursorChannelClient *ccc, PipeItem *item) { switch (item->type) { case PIPE_ITEM_TYPE_CURSOR: { CursorPipeItem *cursor_pipe_item = SPICE_CONTAINEROF(item, CursorPipeItem, base); put_cursor_pipe_item(ccc, cursor_pipe_item); break; } case PIPE_ITEM_TYPE_INVAL_ONE: case PIPE_ITEM_TYPE_VERB: case PIPE_ITEM_TYPE_CURSOR_INIT: case PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE: free(item); break; default: spice_error("invalid pipe item type"); } }
static VALUE subslr(VALUE self, VALUE method, VALUE target, VALUE et, VALUE fixref, VALUE abcorr, VALUE obsrvr) { //Output double sub_solar_epoch, surface_point[3], surface_vector[3]; //Arrays that we return to Ruby VALUE rb_vector = rb_ary_new(); VALUE rb_point = rb_ary_new(); subslr_c(StringValuePtr(method), RB_SYM2STR(target), NUM2DBL(et), RB_SYM2STR(fixref), RB_SYM2STR(abcorr), RB_SYM2STR(obsrvr), surface_point, &sub_solar_epoch, surface_vector); if(spice_error(SPICE_ERROR_SHORT)) return Qnil; rb_point = rb_nmatrix_dense_create(FLOAT64, (size_t *) VECTOR_SHAPE, 2, (void *) surface_point, 3); rb_vector = rb_nmatrix_dense_create(FLOAT64, (size_t *) VECTOR_SHAPE, 2, (void *) surface_vector, 3); return rb_ary_new3(3, rb_point, rb_vector, DBL2NUM(sub_solar_epoch)); }
void image_cache_localize(ImageCache *cache, SpiceImage **image_ptr, SpiceImage *image_store, Drawable *drawable) { SpiceImage *image = *image_ptr; if (image == NULL) { spice_assert(drawable != NULL); spice_assert(drawable->red_drawable->self_bitmap_image != NULL); *image_ptr = drawable->red_drawable->self_bitmap_image; return; } if (image_cache_hit(cache, image->descriptor.id)) { image_store->descriptor = image->descriptor; image_store->descriptor.type = SPICE_IMAGE_TYPE_FROM_CACHE; image_store->descriptor.flags = 0; *image_ptr = image_store; return; } switch (image->descriptor.type) { case SPICE_IMAGE_TYPE_QUIC: { image_store->descriptor = image->descriptor; image_store->u.quic = image->u.quic; *image_ptr = image_store; #ifdef IMAGE_CACHE_AGE image_store->descriptor.flags |= SPICE_IMAGE_FLAGS_CACHE_ME; #else if (image_store->descriptor.width * image->descriptor.height >= 640 * 480) { image_store->descriptor.flags |= SPICE_IMAGE_FLAGS_CACHE_ME; } #endif break; } case SPICE_IMAGE_TYPE_BITMAP: case SPICE_IMAGE_TYPE_SURFACE: /* nothing */ break; default: spice_error("invalid image type"); } }
static void smartcard_channel_send_item(RedChannelClient *rcc, PipeItem *item) { SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); switch (item->type) { case PIPE_ITEM_TYPE_ERROR: smartcard_channel_send_error(rcc, m, item); break; case PIPE_ITEM_TYPE_SMARTCARD_DATA: smartcard_channel_send_msg(rcc, m, item); break; case PIPE_ITEM_TYPE_SMARTCARD_MIGRATE_DATA: smartcard_channel_send_migrate_data(rcc, m, item); break; default: spice_error("bad pipe item %d", item->type); free(item); return; } red_channel_client_begin_send_message(rcc); }
static int spicevmc_channel_client_handle_migrate_data(RedChannelClient *rcc, uint32_t size, void *message) { SpiceMigrateDataHeader *header; SpiceMigrateDataSpiceVmc *mig_data; SpiceVmcState *state; state = spicevmc_red_channel_client_get_state(rcc); header = (SpiceMigrateDataHeader *)message; mig_data = (SpiceMigrateDataSpiceVmc *)(header + 1); spice_assert(size >= sizeof(SpiceMigrateDataHeader) + sizeof(SpiceMigrateDataSpiceVmc)); if (!migration_protocol_validate_header(header, SPICE_MIGRATE_DATA_SPICEVMC_MAGIC, SPICE_MIGRATE_DATA_SPICEVMC_VERSION)) { spice_error("bad header"); return FALSE; } return spice_char_device_state_restore(state->chardev_st, &mig_data->base); }
static void smartcard_char_device_notify_reader_remove(SmartCardDeviceState *st) { SpiceCharDeviceWriteBuffer *write_buf; VSCMsgHeader *vheader; if (!st->reader_added) { spice_debug("reader add was never sent to the device"); return; } write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(vheader)); if (!write_buf) { spice_error("failed to allocate write buffer"); return; } st->reader_added = FALSE; vheader = (VSCMsgHeader *)write_buf->buf; vheader->type = VSC_ReaderRemove; vheader->reader_id = st->reader_id; vheader->length = 0; smartcard_channel_write_to_reader(write_buf); }