/* * Asynchronous I/O callback launched when framebuffer notifications are ready * to be read. * Param: * opaque - FrameBufferImpl instance. */ static void _fbUpdatesImpl_io_callback(void* opaque, int fd, unsigned events) { FrameBufferImpl* fbi = opaque; int ret; // Read updates while they are immediately available. for (;;) { // Read next chunk of data. ret = HANDLE_EINTR( socket_recv(fbi->sock, fbi->reader_buffer + fbi->reader_offset, fbi->reader_bytes - fbi->reader_offset)); if (ret < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { // Chunk is not avalable at this point. Come back later. return; } if (ret <= 0) { /* disconnection ! */ derror("Unable to receive framebuffer data: %s\n", ret < 0 ? strerror(errno), "unexpected disconnection"); fbUpdatesImpl_destroy(); return; } fbi->reader_offset += ret; if (fbi->reader_offset != fbi->reader_bytes) { // There are still some data left in the pipe. continue; } // All expected data has been read. Time to change the state. if (fbi->fb_state == EXPECTS_HEADER) { // Update header has been read. Prepare for the pixels. fbi->fb_state = EXPECTS_PIXELS; fbi->reader_offset = 0; fbi->reader_bytes = fbi->update_header.w * fbi->update_header.h * (fbi->bits_per_pixel / 8); fbi->reader_buffer = malloc(fbi->reader_bytes); if (fbi->reader_buffer == NULL) { APANIC("Unable to allocate memory for framebuffer update\n"); } } else { // Pixels have been read. Prepare for the header. uint8_t* pixels = fbi->reader_buffer; fbi->fb_state = EXPECTS_HEADER; fbi->reader_offset = 0; fbi->reader_bytes = sizeof(FBUpdateMessage); fbi->reader_buffer = (uint8_t*)&fbi->update_header; // Perform the update. Note that pixels buffer must be freed there. _update_rect(fbi->fb, fbi->update_header.x, fbi->update_header.y, fbi->update_header.w, fbi->update_header.h, fbi->bits_per_pixel, pixels); } }
void Viewport::set_rect(const Rect2& p_rect) { if (rect==p_rect) return; rect=p_rect; _update_rect(); _update_stretch_transform(); }
void Viewport::set_size_override_stretch(bool p_enable) { if (p_enable==size_override_stretch) return; size_override_stretch=p_enable; if (size_override) { _update_rect(); } _update_stretch_transform(); }
void Viewport::set_size_override(bool p_enable, const Size2& p_size, const Vector2 &p_margin) { if (size_override==p_enable && p_size==size_override_size) return; size_override=p_enable; if (p_size.x>=0 || p_size.y>=0) { size_override_size=p_size; } size_override_margin=p_margin; _update_rect(); _update_stretch_transform(); }
void Viewport::_notification(int p_what) { switch( p_what ) { case NOTIFICATION_ENTER_SCENE: { if (!render_target) _vp_enter_scene(); this->parent=NULL; Node *parent=get_parent(); if (parent) { while(parent && !(this->parent=parent->cast_to<Viewport>())) { parent=parent->get_parent(); } } current_canvas=find_world_2d()->get_canvas(); VisualServer::get_singleton()->viewport_set_scenario(viewport,find_world()->get_scenario()); VisualServer::get_singleton()->viewport_attach_canvas(viewport,current_canvas); _update_listener(); _update_listener_2d(); _update_rect(); if (world_2d.is_valid()) { find_world_2d()->_register_viewport(this,Rect2()); //best to defer this and not do it here, as it can annoy a lot of setup logic if user //adds a node and then moves it, will get enter/exit screen/viewport notifications //unnecesarily // update_worlds(); } add_to_group("_viewports"); } break; case NOTIFICATION_READY: { #ifndef _3D_DISABLED if (cameras.size() && !camera) { //there are cameras but no current camera, pick first in tree and make it current Camera *first=NULL; for(Set<Camera*>::Element *E=cameras.front();E;E=E->next()) { if (first==NULL || first->is_greater_than(E->get())) { first=E->get(); } } if (first) first->make_current(); } #endif } break; case NOTIFICATION_EXIT_SCENE: { if (world_2d.is_valid()) world_2d->_remove_viewport(this); if (!render_target) _vp_exit_scene(); VisualServer::get_singleton()->viewport_set_scenario(viewport,RID()); SpatialSoundServer::get_singleton()->listener_set_space(listener,RID()); VisualServer::get_singleton()->viewport_remove_canvas(viewport,current_canvas); remove_from_group("_viewports"); } break; } }
void Viewport::_parent_resized() { _update_rect(); }