void vncClientUpdateThread::EnableUpdates(BOOL enable) { // ALWAYS call this with the UpdateLock held! if (enable) { vnclog.Print(LL_INTINFO, VNCLOG("enable update thread\n")); } else { vnclog.Print(LL_INTINFO, VNCLOG("disable update thread\n")); } m_enable = enable; m_signal->signal(); m_sync_sig->wait(); vnclog.Print(LL_INTINFO, VNCLOG("enable/disable synced\n")); }
void vncClientUpdateThread::Kill() { vnclog.Print(LL_INTINFO, VNCLOG("kill update thread\n")); omni_mutex_lock l(m_client->GetUpdateLock()); m_active=FALSE; m_signal->signal(); }
void vncClientUpdateThread::Trigger() { // ALWAYS lock client UpdateLock before calling this! // Only trigger an update if protocol is enabled if (m_client->m_disable_protocol == 0) { m_signal->signal(); } }
void vncDesktopThread::ReturnVal(BOOL result) { omni_mutex_lock l(m_returnLock); m_returnset = TRUE; m_return = result; m_returnsig->signal(); }
int EmClipboardWidget::handle (int event) { // It's a "paste" event, meaning that our application has requested // data to paste, and it just showed up from the X server. if (event == FL_PASTE) { // Get exclusive access to our clipboard data. omni_mutex_lock lock (gClipboardMutex); // Say that the data is here. gClipboardPendingIncomingData = false; gClipboardHaveIncomingData = true; // Copy the data to the host data clipboard. The Palm-specific // clipboard will remain empty, and the host data will get // convert to it on demand. gClipboardDataPalm.clear (); gClipboardDataHost.clear (); copy ((char*) Fl::e_text, (char*) Fl::e_text + Fl::e_length, back_inserter (gClipboardDataHost)); // Tell the CPU thread that the new data is here. gClipboardCondition.broadcast (); // Return that we handled the event. return 1; } // Return that we didn't handle the event. return 0; }
BOOL vncDesktopThread::Init(vncDesktop *desktop, vncServer *server) { // Save the server pointer m_server = server; m_desktop = desktop; m_returnset = FALSE; m_returnsig = new omni_condition(&m_returnLock); // Start the thread start_undetached(); // Wait for the thread to let us know if it failed to init { omni_mutex_lock l(m_returnLock); while (!m_returnset) { m_returnsig->wait(); } } return m_return; }
Bool EmApplicationFltk::PrvIdleClipboard (void) { omni_mutex_lock lock (gClipboardMutex); // See if there's anything outgoing. if (gClipboardHaveOutgoingData) { // Get the widget that FLTK requires for clipboard management. Fl_Widget* w = this->PrvGetClipboardWidget (); EmAssert (w); // Tell FLTK the data to make available to other X programs if they need // to know the current selection. We make a local copy of the data in // case ... <something about race conditions>. fClipboardData = gClipboardDataHost; Fl::selection (*w, (const char*) &fClipboardData[0], (int) fClipboardData.size ()); // Clear the flag saying that we changed the clipboard. gClipboardHaveOutgoingData = false; } // See if there's a request for incoming data. if (gClipboardNeedIncomingData) { // Clear the flag saying that we need to ask for the // current selection. gClipboardNeedIncomingData = false; // FLTK only sends a FL_PASTE event if a selection exists. If there // is no selection, we note that ourselves instead of waiting for an // event that will never arrive. // // !!! Do we get a FL_PASTE event if there is a primary selection // but it can't be converted to XA_STRING? We might still wait // forever in that case. if (XGetSelectionOwner (fl_display, XA_PRIMARY) != None) { gClipboardPendingIncomingData = true; // Get the widget that FLTK requires for clipboard management. Fl_Widget* w = PrvGetClipboardWidget (); EmAssert (w); // Our clipboard widget may get called in this // context. It will try to acquire the clipboard // mutex, so give it up here. omni_mutex_unlock unlock (gClipboardMutex); // Tell FLTK to get the clipboard data. Usually, this will // require sending a request to the X server to get the // data from the application holding the current selection. // When the remote application responds, we'll get notified // via an FL_PASTE event sent to our widget's handle() method. Fl::paste (*w); } else { gClipboardHaveIncomingData = true; gClipboardCondition.broadcast (); } } return !gClipboardPendingIncomingData; }
void* vncClientUpdateThread::run_undetached(void *arg) { rfb::SimpleUpdateTracker update; rfb::Region2D clipregion; char *clipboard_text = 0; update.enable_copyrect(true); BOOL send_palette = FALSE; unsigned long updates_sent=0; vnclog.Print(LL_INTINFO, VNCLOG("starting update thread\n")); // Set client update threads to high priority // *** set_priority(omni_thread::PRIORITY_HIGH); while (1) { // Block waiting for an update to send { omni_mutex_lock l(m_client->GetUpdateLock()); m_client->m_incr_rgn = m_client->m_incr_rgn.union_(clipregion); // We block as long as updates are disabled, or the client // isn't interested in them, unless this thread is killed. while (m_active && ( !m_enable || ( m_client->m_update_tracker.get_changed_region().intersect(m_client->m_incr_rgn).is_empty() && m_client->m_update_tracker.get_copied_region().intersect(m_client->m_incr_rgn).is_empty() && !m_client->m_clipboard_text ) ) ) { // Issue the synchronisation signal, to tell other threads // where we have got to m_sync_sig->broadcast(); // Wait to be kicked into action m_signal->wait(); } // If the thread is being killed then quit if (!m_active) break; // SEND AN UPDATE! // The thread is active, updates are enabled, and the // client is expecting an update - let's see if there // is anything to send. // Has the palette changed? send_palette = m_client->m_palettechanged; m_client->m_palettechanged = FALSE; // Fetch the incremental region clipregion = m_client->m_incr_rgn; m_client->m_incr_rgn.clear(); // Get the clipboard data, if any if (m_client->m_clipboard_text) { clipboard_text = m_client->m_clipboard_text; m_client->m_clipboard_text = 0; } // Get the update details from the update tracker m_client->m_update_tracker.flush_update(update, clipregion); // Render the mouse if required if (m_client->m_mousemoved) { // Re-render its old location m_client->m_oldmousepos = m_client->m_oldmousepos.intersect(m_client->m_fullscreen); if (!m_client->m_oldmousepos.is_empty()) update.add_changed(m_client->m_oldmousepos); // And render its new one m_client->m_encodemgr.m_buffer->GetMousePos(m_client->m_oldmousepos); m_client->m_oldmousepos = m_client->m_oldmousepos.intersect(m_client->m_fullscreen); if (!m_client->m_oldmousepos.is_empty()) update.add_changed(m_client->m_oldmousepos); m_client->m_mousemoved = FALSE; } // Get the encode manager to update the client back buffer m_client->m_encodemgr.GrabRegion(update.get_changed_region()); } // SEND THE CLIPBOARD // If there is clipboard text to be sent then send it if (clipboard_text) { rfbServerCutTextMsg message; message.length = Swap32IfLE(strlen(clipboard_text)); if (!m_client->SendRFBMsg(rfbServerCutText, (BYTE *) &message, sizeof(message))) { m_client->m_socket->Close(); } if (!m_client->m_socket->SendExact(clipboard_text, strlen(clipboard_text))) { m_client->m_socket->Close(); } free(clipboard_text); clipboard_text = 0; } // SEND AN UPDATE // We do this without holding locks, to avoid network problems // stalling the server. // Update the client palette if necessary if (send_palette) { m_client->SendPalette(); } // Send updates to the client - this implicitly clears // the supplied update tracker if (m_client->SendUpdate(update)) { updates_sent++; clipregion.clear(); } } vnclog.Print(LL_INTINFO, VNCLOG("stopping update thread\n")); vnclog.Print(LL_INTERR, "client sent %lu updates\n", updates_sent); return 0; }