Beispiel #1
0
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"));
}
Beispiel #2
0
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();
}
Beispiel #3
0
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();
	}
}
Beispiel #4
0
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;
}
Beispiel #6
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;
}
Beispiel #8
0
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;
}