fd_dispatcher(int port, size_t thread_cnt) : m_acc(m_disp, ranger::event::endpoint(port)) { m_acc.set_event_handler([this] (ranger::event::tcp_acceptor& acc, int fd) { return m_workers[m_worker_idx++ % m_workers.size()].take_fd(fd); }); decltype(m_workers) workers(thread_cnt); for (auto i = workers.begin(); i != workers.end(); ++i) { auto conn_pair = ranger::event::tcp_connection::create_pair(m_disp, i->event_dispatcher()); conn_pair.first.set_event_handler([] (ranger::event::tcp_connection& conn, ranger::event::tcp_connection::event_code what) { switch (what) { case ranger::event::tcp_connection::event_code::timeout: case ranger::event::tcp_connection::event_code::error: case ranger::event::tcp_connection::event_code::eof: conn.close(); break; default: break; } }); i->set_external_connection(std::move(conn_pair.first)); i->set_internal_connection(std::move(conn_pair.second)); } m_workers = std::move(workers); }
// In delayed rendering, Windows requires us to SetClipboardData before we return from // handling WM_RENDERFORMAT. Therefore, we try our best by sending CLIPBOARD_REQUEST to the // agent, while waiting alertably for a while (hoping for good) for receiving CLIPBOARD data // or CLIPBOARD_RELEASE from the agent, which both will signal clipboard_event. // In case of unsupported format, wrong clipboard owner or no clipboard capability, we do nothing in // WM_RENDERFORMAT and return immediately. // FIXME: need to be handled using request queue void VDAgent::on_clipboard_request(UINT format) { uint32_t type; if (_clipboard_owner != owner_client) { vd_printf("Received render request event for format %u" "while clipboard is not owned by client", format); return; } if (!(type = get_clipboard_type(format))) { vd_printf("Unsupported clipboard format %u", format); return; } if (!VD_AGENT_HAS_CAPABILITY(_client_caps, _client_caps_size, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) { return; } VDAgentClipboardRequest request = {type}; if (!write_message(VD_AGENT_CLIPBOARD_REQUEST, sizeof(request), &request)) { return; } _clipboard_tick = GetTickCount(); while (_running && _clipboard_tick && GetTickCount() < _clipboard_tick + VD_CLIPBOARD_TIMEOUT_MS) { event_dispatcher(VD_CLIPBOARD_TIMEOUT_MS, 0); } if (_clipboard_tick) { vd_printf("Clipboard wait timeout"); _clipboard_tick = 0; } else { // reset incoming message state only upon completion (even after timeout) cleanup_in_msg(); } }
/* loop inspired by yay * http://freecode.com/projects/yay */ Uint32 event_loop(void) { char caption[256]; Uint16 quit = 0; Uint32 frame = 0; int play_yuv = 0; unsigned int start_ticks = 0; while (!quit) { set_caption(caption, frame, 256); SDL_WM_SetCaption(caption, NULL); /* wait for SDL event */ if (P.mode == NONE || P.mode == MASTER) { SDL_WaitEvent(&event); } else if (P.mode == SLAVE) { if (!event_dispatcher()) { SDL_WaitEvent(&event); } } switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_SPACE: play_yuv = 1; /* play it, sam! */ while (play_yuv) { start_ticks = SDL_GetTicks(); set_caption(caption, frame, 256); SDL_WM_SetCaption( caption, NULL ); /* check for next frame existing */ if (read_frame()) { draw_frame(); /* insert delay for real time viewing */ if (SDL_GetTicks() - start_ticks < 40) SDL_Delay(40 - (SDL_GetTicks() - start_ticks)); frame++; send_message(NEXT); } else { play_yuv = 0; } /* check for any key event */ if (SDL_PollEvent(&event)) { if (event.type == SDL_KEYDOWN) { /* stop playing */ play_yuv = 0; } } } break; case SDLK_RIGHT: /* next frame */ /* check for next frame existing */ if (read_frame()) { draw_frame(); frame++; send_message(NEXT); } break; case SDLK_LEFT: /* previous frame */ if (frame > 1) { frame--; fseek(fd, ((frame-1) * P.frame_size), SEEK_SET); if (P.diff) { fseek(P.fd2, ((frame-1) * P.frame_size), SEEK_SET); } read_frame(); draw_frame(); send_message(PREV); } break; case SDLK_UP: /* zoom in */ P.zoom++; set_zoom_rect(); screen = SDL_SetVideoMode(P.zoom_width, P.zoom_height, P.bpp, P.vflags); video_rect.w = P.zoom_width; video_rect.h = P.zoom_height; SDL_DisplayYUVOverlay(my_overlay, &video_rect); send_message(ZOOM_IN); break; case SDLK_DOWN: /* zoom out */ P.zoom--; set_zoom_rect(); screen = SDL_SetVideoMode(P.zoom_width, P.zoom_height, P.bpp, P.vflags); video_rect.w = P.zoom_width; video_rect.h = P.zoom_height; SDL_DisplayYUVOverlay(my_overlay, &video_rect); send_message(ZOOM_OUT); break; case SDLK_r: /* rewind */ if (frame > 1) { frame = 1; fseek(fd, 0, SEEK_SET); if (P.diff) { fseek(P.fd2, 0, SEEK_SET); } read_frame(); draw_frame(); send_message(REW); } break; case SDLK_g: /* display grid */ P.grid = ~P.grid; if (P.zoom < 1) P.grid = 0; draw_frame(); break; case SDLK_m: /* show mb-data on stdout */ P.mb = ~P.mb; if (P.zoom < 1) P.mb = 0; draw_frame(); break; case SDLK_F5: /* Luma data only */ P.y_only = ~P.y_only; P.cb_only = 0; P.cr_only = 0; draw_frame(); send_message(Y_ONLY); break; case SDLK_F6: /* Cb data only */ P.cb_only = ~P.cb_only; P.y_only = 0; P.cr_only = 0; draw_frame(); send_message(CB_ONLY); break; case SDLK_F7: /* Cr data only */ P.cr_only = ~P.cr_only; P.y_only = 0; P.cb_only = 0; send_message(CR_ONLY); draw_frame(); break; case SDLK_F8: /* display all color planes */ P.y_only = 0; P.cb_only = 0; P.cr_only = 0; draw_frame(); send_message(ALL_PLANES); break; case SDLK_h: /* histogram */ P.hist = ~P.hist; draw_frame(); break; case SDLK_F1: /* MASTER-mode */ if (create_message_queue()) { P.mode = MASTER; } break; case SDLK_F2: /* SLAVE-mode */ if (P.mode == MASTER) { destroy_message_queue(); } if (connect_message_queue()) { P.mode = SLAVE; } break; case SDLK_F3: /* NONE-mode */ destroy_message_queue(); P.mode = NONE; break; case SDLK_q: /* quit */ quit = 1; send_message(QUIT); break; default: break; } /* switch key */ break; case SDL_QUIT: quit = 1; break; case SDL_VIDEOEXPOSE: SDL_DisplayYUVOverlay(my_overlay, &video_rect); break; case SDL_MOUSEBUTTONDOWN: /* If the left mouse button was pressed */ if (event.button.button == SDL_BUTTON_LEFT ) { show_mb(event.button.x, event.button.y); } break; default: break; } /* switch event type */ } /* while */ return quit; }
void VDAgent::input_desktop_message_loop() { TCHAR desktop_name[MAX_PATH]; HDESK hdesk; hdesk = OpenInputDesktop(0, FALSE, GENERIC_ALL); if (!hdesk) { vd_printf("OpenInputDesktop() failed: %lu", GetLastError()); _running = false; return; } if (!SetThreadDesktop(hdesk)) { vd_printf("SetThreadDesktop failed %lu", GetLastError()); _running = false; return; } if (GetUserObjectInformation(hdesk, UOI_NAME, desktop_name, sizeof(desktop_name), NULL)) { vd_printf("Desktop: %S", desktop_name); } else { vd_printf("GetUserObjectInformation failed %lu", GetLastError()); } // loading the display settings for the current session's logged on user only // after 1) we receive logon event, and 2) the desktop switched from Winlogon if (_tcscmp(desktop_name, TEXT("Winlogon")) == 0) { _logon_desktop = true; } else { // first load after connection if (!_display_setting_initialized) { vd_printf("First display setting"); _display_setting.load(); _display_setting_initialized = true; } else if (_logon_occured && _logon_desktop) { vd_printf("LOGON display setting"); _display_setting.load(); } _logon_occured = false; _logon_desktop = false; } _hwnd = CreateWindow(VD_AGENT_WINCLASS_NAME, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); if (!_hwnd) { vd_printf("CreateWindow() failed: %lu", GetLastError()); _running = false; return; } if (!WTSRegisterSessionNotification(_hwnd, NOTIFY_FOR_ALL_SESSIONS)) { vd_printf("WTSRegisterSessionNotification() failed: %lu", GetLastError()); } if (_system_version == SYS_VER_WIN_7_CLASS) { _add_clipboard_listener(_hwnd); } else { _hwnd_next_viewer = SetClipboardViewer(_hwnd); } while (_running && !_desktop_switch) { event_dispatcher(INFINITE, QS_ALLINPUT); } _desktop_switch = false; if (_pending_input) { KillTimer(_hwnd, VD_TIMER_ID); _pending_input = false; } if (_system_version == SYS_VER_WIN_7_CLASS) { _remove_clipboard_listener(_hwnd); } else { ChangeClipboardChain(_hwnd, _hwnd_next_viewer); } WTSUnRegisterSessionNotification(_hwnd); DestroyWindow(_hwnd); CloseDesktop(hdesk); }