Esempio n. 1
0
static BOOL xf_event_ClientMessage(xfInfo* xfi, XEvent* event, BOOL app)
{
	if ((event->xclient.message_type == xfi->WM_PROTOCOLS)
	    && ((Atom) event->xclient.data.l[0] == xfi->WM_DELETE_WINDOW))
	{
		if (app)
		{
			DEBUG_X11("RAIL window closed");
			rdpWindow* window;
			rdpRail* rail = ((rdpContext*) xfi->context)->rail;

			window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window);

			if (window != NULL)
			{
				xf_rail_send_client_system_command(xfi, window->windowId, SC_CLOSE);
			}

			return TRUE;
		}
		else
		{
			DEBUG_X11("Main window closed");
			return FALSE;
		}
	}

	return TRUE;
}
Esempio n. 2
0
static void xf_cliprdr_process_html(clipboardContext* cb, uint8* data, int size)
{
	char* start_str;
	char* end_str;
	int start;
	int end;

	start_str = strstr((char*) data, "StartHTML:");
	end_str = strstr((char*) data, "EndHTML:");
	if (start_str == NULL || end_str == NULL)
	{
		DEBUG_X11("invalid HTML clipboard format");
		return;
	}
	start = atoi(start_str + 10);
	end = atoi(end_str + 8);
	if (start > size || end > size || start >= end)
	{
		DEBUG_X11("invalid HTML offset");
		return;
	}

	cb->data = (uint8*) xmalloc(size - start + 1);
	memcpy(cb->data, data + start, end - start);
	cb->data_length = end - start;
	crlf2lf(cb->data, &cb->data_length);
}
Esempio n. 3
0
static void xf_cliprdr_get_requested_targets(xfInfo* xfi)
{
	int num;
	int i, j;
	Atom atom;
	int format;
	BYTE* data = NULL;
	unsigned long length, bytes_left;
	RDP_CB_FORMAT_LIST_EVENT* event;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	XGetWindowProperty(xfi->display, xfi->drawable, cb->property_atom,
		0, 200, 0, XA_ATOM, &atom, &format, &length, &bytes_left, &data);

	DEBUG_X11_CLIPRDR("type=%d format=%d length=%d bytes_left=%d",
		(int) atom, format, (int) length, (int) bytes_left);

	if (length > 0)
	{
		event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
				CliprdrChannel_FormatList, NULL, NULL);

		event->formats = (UINT32*) malloc(sizeof(UINT32) * cb->num_format_mappings);
		num = 0;

		for (i = 0; i < length; i++)
		{
			atom = ((Atom*) data)[i];
			DEBUG_X11("atom %d", (int) atom);

			for (j = 0; j < cb->num_format_mappings; j++)
			{
				if (cb->format_mappings[j].target_format == atom)
				{
					DEBUG_X11("found format %d for atom %d",
						cb->format_mappings[j].format_id, (int)atom);
					event->formats[num++] = cb->format_mappings[j].format_id;
					break;
				}
			}
		}

		event->num_formats = num;
		XFree(data);

		freerdp_channels_send_event(cb->channels, (wMessage*) event);
	}
	else
	{
		if (data)
			XFree(data);

		xf_cliprdr_send_null_format_list(xfi);
	}
}
Esempio n. 4
0
static void xf_cliprdr_get_requested_targets(xfInfo* xfi)
{
	int num;
	int i, j;
	Atom atom;
	int format;
	uint8* data = NULL;
	unsigned long len, bytes_left;
	RDP_CB_FORMAT_LIST_EVENT* event;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	XGetWindowProperty(xfi->display, xfi->window->handle, cb->property_atom,
		0, 200, 0, XA_ATOM,
		&atom, &format, &len, &bytes_left, &data);

	DEBUG_X11("type=%d format=%d len=%d bytes_left=%d",
		(int)atom, format, (int)len, (int)bytes_left);

	if (len > 0)
	{
		event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR,
			RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL);

		event->formats = (uint32*) xmalloc(sizeof(uint32) * cb->num_format_mappings);
		num = 0;
		for (i = 0; i < len; i++)
		{
			atom = ((Atom*)data)[i];
			DEBUG_X11("atom %d", (int)atom);
			for (j = 0; j < cb->num_format_mappings; j++)
			{
				if (cb->format_mappings[j].target_format == atom)
				{
					DEBUG_X11("found format %d for atom %d",
						cb->format_mappings[j].format_id, (int)atom);
					event->formats[num++] = cb->format_mappings[j].format_id;
					break;
				}
			}
		}
		event->num_formats = num;
		XFree(data);

		freerdp_chanman_send_event(cb->chanman, (RDP_EVENT*) event);
	}
	else
	{
		if (data)
		{
			XFree(data);
		}
		xf_cliprdr_send_null_format_list(xfi);
	}
}
Esempio n. 5
0
static BOOL xf_event_ClientMessage(xfContext* xfc, XEvent* event, BOOL app)
{
	if ((event->xclient.message_type == xfc->WM_PROTOCOLS)
	    && ((Atom) event->xclient.data.l[0] == xfc->WM_DELETE_WINDOW))
	{
		if (app)
		{
			xfAppWindow* appWindow;
			appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);

			if (appWindow)
			{
				xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
			}

			return TRUE;
		}
		else
		{
			DEBUG_X11("Main window closed");
			return FALSE;
		}
	}

	return TRUE;
}
Esempio n. 6
0
static void xf_cliprdr_send_raw_format_list(xfInfo* xfi)
{
	Atom type;
	uint8* format_data;
	int format, result;
	unsigned long len, bytes_left;
	RDP_CB_FORMAT_LIST_EVENT* event;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	result = XGetWindowProperty(xfi->display, cb->root_window,
		cb->property_atom, 0, 3600, 0, XA_STRING,
		&type, &format, &len, &bytes_left, (unsigned char**) &format_data);
	if (result != Success)
	{
		DEBUG_WARN("XGetWindowProperty failed");
		return;
	}
	DEBUG_X11("format=%d len=%d bytes_left=%d", format, (int)len, (int)bytes_left);

	event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR,
		RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL);

	event->raw_format_data = (uint8*) xmalloc(len);
	memcpy(event->raw_format_data, format_data, len);
	event->raw_format_data_size = len;
	XFree(format_data);

	freerdp_chanman_send_event(cb->chanman, (RDP_EVENT*) event);
}
Esempio n. 7
0
void xf_process_cliprdr_event(xfInfo* xfi, RDP_EVENT* event)
{
	switch (event->event_type)
	{
		case RDP_EVENT_TYPE_CB_SYNC:
			xf_cliprdr_process_cb_sync_event(xfi);
			break;

		case RDP_EVENT_TYPE_CB_FORMAT_LIST:
			xf_cliprdr_process_cb_format_list_event(xfi, (RDP_CB_FORMAT_LIST_EVENT*) event);
			break;

		case RDP_EVENT_TYPE_CB_DATA_REQUEST:
			xf_cliprdr_process_cb_data_request_event(xfi, (RDP_CB_DATA_REQUEST_EVENT*) event);
			break;

		case RDP_EVENT_TYPE_CB_DATA_RESPONSE:
			xf_cliprdr_process_cb_data_response_event(xfi, (RDP_CB_DATA_RESPONSE_EVENT*) event);
			break;

		default:
			DEBUG_X11("unknown event type %d", event->event_type);
			break;
	}
}
Esempio n. 8
0
/**
 * Post an event from the client to the X server
 */
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom,
                        unsigned int numArgs, ...)
{
	XEvent xevent;
	unsigned int i;
	va_list argp;
	va_start(argp, numArgs);
	ZeroMemory(&xevent, sizeof(XEvent));
	xevent.xclient.type = ClientMessage;
	xevent.xclient.serial = 0;
	xevent.xclient.send_event = False;
	xevent.xclient.display = xfc->display;
	xevent.xclient.window = window;
	xevent.xclient.message_type = atom;
	xevent.xclient.format = 32;

	for (i = 0; i < numArgs; i++)
	{
		xevent.xclient.data.l[i] = va_arg(argp, int);
	}

	DEBUG_X11("Send ClientMessage Event: wnd=0x%04lX", (unsigned long) xevent.xclient.window);
	XSendEvent(xfc->display, RootWindowOfScreen(xfc->screen), False,
	           SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
	XSync(xfc->display, False);
	va_end(argp);
}
Esempio n. 9
0
static void xf_cliprdr_process_dib(clipboardContext* cb, uint8* data, int size)
{
	STREAM* s;
	uint16 bpp;
	uint32 offset;
	uint32 ncolors;

	/* size should be at least sizeof(BITMAPINFOHEADER) */
	if (size < 40)
	{
		DEBUG_X11("dib size %d too short", size);
		return;
	}

	s = stream_new(0);
	stream_attach(s, data, size);
	stream_seek(s, 14);
	stream_read_uint16(s, bpp);
	stream_read_uint32(s, ncolors);
	offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0);
	stream_detach(s);
	stream_free(s);

	DEBUG_X11("offset=%d bpp=%d ncolors=%d",
		offset, bpp, ncolors);

	s = stream_new(14 + size);
	stream_write_uint8(s, 'B');
	stream_write_uint8(s, 'M');
	stream_write_uint32(s, 14 + size);
	stream_write_uint32(s, 0);
	stream_write_uint32(s, offset);
	stream_write(s, data, size);

	cb->data = stream_get_head(s);
	cb->data_length = stream_get_length(s);
	stream_detach(s);
	stream_free(s);
}
Esempio n. 10
0
static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_REQUEST_EVENT* event)
{
	int i;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	DEBUG_X11("format %d", event->format);

	if (xf_cliprdr_is_self_owned(xfi))
	{
		/* CB_FORMAT_RAW */
		i = 0;
		XChangeProperty(xfi->display, xfi->window->handle, cb->property_atom,
			XA_INTEGER, 32, PropModeReplace,
			(unsigned char*) &event->format, 1);
	}
	else
	{
		i = xf_cliprdr_select_format_by_id(cb, event->format);
	}
	if (i < 0)
	{
		DEBUG_X11("unsupported format requested");
		xf_cliprdr_send_null_data_response(xfi);
	}
	else
	{
		cb->request_index = i;

		DEBUG_X11("target=%d", (int)cb->format_mappings[i].target_format);

		XConvertSelection(xfi->display, cb->clipboard_atom,
			cb->format_mappings[i].target_format, cb->property_atom,
			xfi->window->handle, CurrentTime);
		XFlush(xfi->display);
		/* After this point, we expect a SelectionNotify event from the clipboard owner. */
	}
}
Esempio n. 11
0
boolean xf_cliprdr_process_property_notify(xfInfo* xfi, XEvent* xevent)
{
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	if (xevent->xproperty.atom != cb->property_atom)
		return False; /* Not cliprdr-related */

	if (xevent->xproperty.window == cb->root_window)
	{
		DEBUG_X11("root window PropertyNotify");
		xf_cliprdr_send_format_list(xfi);
	}
	else if (xevent->xproperty.window == xfi->window->handle &&
		xevent->xproperty.state == PropertyNewValue &&
		cb->incr_starts &&
		cb->request_index >= 0)
	{
		DEBUG_X11("cliprdr window PropertyNotify");
		xf_cliprdr_get_requested_data(xfi,
			cb->format_mappings[cb->request_index].target_format);
	}

	return True;
}
Esempio n. 12
0
static uint8* xf_cliprdr_process_requested_dib(uint8* data, int* size)
{
	uint8* outbuf;

	/* length should be at least BMP header (14) + sizeof(BITMAPINFOHEADER) */
	if (*size < 54)
	{
		DEBUG_X11("bmp length %d too short", *size);
		return NULL;
	}
	*size -= 14;
	outbuf = (uint8*) xzalloc(*size);
	memcpy(outbuf, data + 14, *size);

	return outbuf;
}
Esempio n. 13
0
static void xf_cliprdr_process_cb_format_list_event(xfInfo* xfi, RDP_CB_FORMAT_LIST_EVENT* event)
{
	int i, j;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	if (cb->data)
	{
		free(cb->data);
		cb->data = NULL;
	}

	if (cb->formats)
		free(cb->formats);

	cb->formats = event->formats;
	cb->num_formats = event->num_formats;
	event->formats = NULL;
	event->num_formats = 0;

	cb->num_targets = 2;

	for (i = 0; i < cb->num_formats; i++)
	{
		for (j = 0; j < cb->num_format_mappings; j++)
		{
			if (cb->formats[i] == cb->format_mappings[j].format_id)
			{
				DEBUG_X11("announce format#%d : %d", i, cb->formats[i]);
				xf_cliprdr_append_target(cb, cb->format_mappings[j].target_format);
			}
		}
	}

	XSetSelectionOwner(xfi->display, cb->clipboard_atom, xfi->drawable, CurrentTime);

	if (event->raw_format_data)
	{
		XChangeProperty(xfi->display, cb->root_window, cb->property_atom,
			XA_STRING, 8, PropModeReplace,
			event->raw_format_data, event->raw_format_data_size);
	}

	XFlush(xfi->display);
}
Esempio n. 14
0
static void xf_cliprdr_send_supported_format_list(xfInfo* xfi)
{
	int i;
	RDP_CB_FORMAT_LIST_EVENT* event;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	DEBUG_X11("");

	event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR,
		RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL);

	event->formats = (uint32*) xmalloc(sizeof(uint32) * cb->num_format_mappings);
	event->num_formats = cb->num_format_mappings;
	for (i = 0; i < cb->num_format_mappings; i++)
	{
		event->formats[i] = cb->format_mappings[i].format_id;
	}

	freerdp_chanman_send_event(cb->chanman, (RDP_EVENT*) event);
}
Esempio n. 15
0
boolean xf_cliprdr_process_selection_notify(xfInfo* xfi, XEvent* xevent)
{
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	if (xevent->xselection.target == cb->targets[1])
	{
		if (xevent->xselection.property == None)
		{
			DEBUG_X11("owner not support TARGETS. sending all format.");
			xf_cliprdr_send_supported_format_list(xfi);
		}
		else
		{
			xf_cliprdr_get_requested_targets(xfi);
		}

		return True;
	}
	else
	{
		return xf_cliprdr_get_requested_data(xfi, xevent->xselection.target);
	}
}
Esempio n. 16
0
BOOL xf_event_process(freerdp* instance, XEvent* event)
{
	BOOL status = TRUE;
	xfInfo* xfi = ((xfContext*) instance->context)->xfi;
	rdpRail* rail = ((rdpContext*) xfi->context)->rail;
	rdpWindow* window;

	if (xfi->remote_app)
	{
		window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);

		if (window) 
		{
			/* Update "current" window for cursor change orders */
			xfi->window = (xfWindow*) window->extra;

			if (xf_event_suppress_events(xfi, window, event))
				return TRUE;
		}
	}

	if (event->type != MotionNotify)
		DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], event->type, (UINT32) event->xany.window);

	switch (event->type)
	{
		case Expose:
			status = xf_event_Expose(xfi, event, xfi->remote_app);
			break;

		case VisibilityNotify:
			status = xf_event_VisibilityNotify(xfi, event, xfi->remote_app);
			break;

		case MotionNotify:
			status = xf_event_MotionNotify(xfi, event, xfi->remote_app);
			break;

		case ButtonPress:
			status = xf_event_ButtonPress(xfi, event, xfi->remote_app);
			break;

		case ButtonRelease:
			status = xf_event_ButtonRelease(xfi, event, xfi->remote_app);
			break;

		case KeyPress:
			status = xf_event_KeyPress(xfi, event, xfi->remote_app);
			break;

		case KeyRelease:
			status = xf_event_KeyRelease(xfi, event, xfi->remote_app);
			break;

		case FocusIn:
			status = xf_event_FocusIn(xfi, event, xfi->remote_app);
			break;

		case FocusOut:
			status = xf_event_FocusOut(xfi, event, xfi->remote_app);
			break;

		case EnterNotify:
			status = xf_event_EnterNotify(xfi, event, xfi->remote_app);
			break;

		case LeaveNotify:
			status = xf_event_LeaveNotify(xfi, event, xfi->remote_app);
			break;

		case NoExpose:
			break;

		case GraphicsExpose:
			break;

		case ConfigureNotify:
			status = xf_event_ConfigureNotify(xfi, event, xfi->remote_app);
			break;

		case MapNotify:
			status = xf_event_MapNotify(xfi, event, xfi->remote_app);
			break;

		case UnmapNotify:
			status = xf_event_UnmapNotify(xfi, event, xfi->remote_app);
			break;

		case ReparentNotify:
			break;

		case MappingNotify:
			status = xf_event_MappingNotify(xfi, event, xfi->remote_app);
			break;

		case ClientMessage:
			status = xf_event_ClientMessage(xfi, event, xfi->remote_app);
			break;

		case SelectionNotify:
			status = xf_event_SelectionNotify(xfi, event, xfi->remote_app);
			break;

		case SelectionRequest:
			status = xf_event_SelectionRequest(xfi, event, xfi->remote_app);
			break;

		case SelectionClear:
			status = xf_event_SelectionClear(xfi, event, xfi->remote_app);
			break;

		case PropertyNotify:
			status = xf_event_PropertyNotify(xfi, event, xfi->remote_app);
			break;
	}

	xf_input_handle_event(xfi, event);

	XSync(xfi->display, FALSE);

	return status;
}
Esempio n. 17
0
int
main(int argc, char ** argv)
{
	int rv;
	xfInfo * xfi;
	pthread_t thread;
	int index = 1;
	char reason_msg[ERRINFO_BUFFER_SIZE];

	setlocale(LC_CTYPE, "");
	if (argc == 1)
	{
		out_args();
		return 0;
	}
	if (!freerdp_global_init())
	{
		printf("Error initializing freerdp\n");
		return 1;
	}
	freerdp_chanman_init();

	freerdp_sem_create(&g_sem, 0);

	while (1)
	{
		xfi = (xfInfo *) malloc(sizeof(xfInfo));
		memset(xfi, 0, sizeof(xfInfo));
		xfi->settings = (rdpSet *) malloc(sizeof(rdpSet));
		xfi->chan_man = freerdp_chanman_new();
		xfi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV));
		memset(xfi->clrconv, 0, sizeof(CLRCONV));

		xfi->clrconv->alpha = 1;
		xfi->clrconv->palette = NULL;

		rv = process_params(xfi, argc, argv, &index);
		if (rv)
		{
			free(xfi->settings);
			freerdp_chanman_free(xfi->chan_man);
			free(xfi);
			break;
		}

		DEBUG_X11("starting thread %d to %s:%d", g_thread_count,
			xfi->settings->server, xfi->settings->tcp_port_rdp);
		if (pthread_create(&thread, 0, thread_func, xfi) == 0)
		{
			g_thread_count++;
		}
	}

	if (g_thread_count > 0)
	{
		DEBUG_X11("main thread, waiting for all threads to exit");
		freerdp_sem_wait(&g_sem);
		DEBUG_X11("main thread, all threads did exit");
	}

	freerdp_chanman_uninit();
	freerdp_global_finish();

	if (g_error_code)
		return g_error_code;
	else if (g_disconnect_reason)
	{
		printf("disconnect: %s\n",
			freerdp_str_disconnect_reason(g_disconnect_reason, reason_msg, ERRINFO_BUFFER_SIZE));
	}

	return exit_code_from_disconnect_reason(g_disconnect_reason);
}
Esempio n. 18
0
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
{
	UINT32 i;
	rdpSettings* settings = xfc->context.settings;
	int startX, startY;
	UINT32 width = window->width;
	UINT32 height = window->height;
	/* xfc->decorations is set by caller depending on settings and whether it is fullscreen or not */
	window->decorations = xfc->decorations;
	/* show/hide decorations (e.g. title bar) as guided by xfc->decorations */
	xf_SetWindowDecorations(xfc, window->handle, window->decorations);
	DEBUG_X11(TAG, "X window decoration set to %d", (int)window->decorations);
	xf_floatbar_toggle_fullscreen(xfc->window->floatbar, fullscreen);

	if (fullscreen)
	{
		xfc->savedWidth = xfc->window->width;
		xfc->savedHeight = xfc->window->height;
		xfc->savedPosX = xfc->window->left;
		xfc->savedPosY = xfc->window->top;
		startX = (settings->DesktopPosX != UINT32_MAX) ? settings->DesktopPosX : 0;
		startY = (settings->DesktopPosY != UINT32_MAX) ? settings->DesktopPosY : 0;
	}
	else
	{
		width = xfc->savedWidth;
		height = xfc->savedHeight;
		startX = xfc->savedPosX;
		startY = xfc->savedPosY;
	}

	/* Determine the x,y starting location for the fullscreen window */
	if (fullscreen)
	{
		/* Initialize startX and startY with reasonable values */
		startX = xfc->context.settings->MonitorDefArray[0].x;
		startY = xfc->context.settings->MonitorDefArray[0].y;

		/* Search all monitors to find the lowest startX and startY values */
		for (i = 0; i < xfc->context.settings->MonitorCount; i++)
		{
			startX = MIN(startX, xfc->context.settings->MonitorDefArray[i].x);
			startY = MIN(startY, xfc->context.settings->MonitorDefArray[i].y);
		}

		/* Lastly apply any monitor shift(translation from remote to local coordinate system)
		 *  to startX and startY values
		 */
		startX += xfc->context.settings->MonitorLocalShiftX;
		startY += xfc->context.settings->MonitorLocalShiftY;
	}

	/*
	  It is safe to proceed with simply toogling _NET_WM_STATE_FULLSCREEN window state on the following conditions:
	       - The window manager supports multiple monitor full screen
	       - The user requested to use a single monitor to render the remote desktop
	 */
	if (xfc->_NET_WM_FULLSCREEN_MONITORS != None || settings->MonitorCount == 1)
	{
		xf_ResizeDesktopWindow(xfc, window, width, height);

		if (fullscreen)
		{
			/* enter full screen: move the window before adding NET_WM_STATE_FULLSCREEN */
			XMoveWindow(xfc->display, window->handle, startX, startY);
		}

		/* Set the fullscreen state */
		xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
		                   fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
		                   xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);

		if (!fullscreen)
		{
			/* leave full screen: move the window after removing NET_WM_STATE_FULLSCREEN */
			XMoveWindow(xfc->display, window->handle, startX, startY);
		}

		/* Set monitor bounds */
		if (settings->MonitorCount > 1)
		{
			xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
			                   xfc->fullscreenMonitors.top,
			                   xfc->fullscreenMonitors.bottom,
			                   xfc->fullscreenMonitors.left,
			                   xfc->fullscreenMonitors.right,
			                   1);
		}
	}
	else
	{
		if (fullscreen)
		{
			xf_SetWindowDecorations(xfc, window->handle, FALSE);

			if (xfc->fullscreenMonitors.top)
			{
				xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
				                   _NET_WM_STATE_ADD,
				                   xfc->fullscreenMonitors.top, 0, 0);
			}
			else
			{
				XSetWindowAttributes xswa;
				xswa.override_redirect = True;
				XChangeWindowAttributes(xfc->display, window->handle, CWOverrideRedirect, &xswa);
				XRaiseWindow(xfc->display, window->handle);
				xswa.override_redirect = False;
				XChangeWindowAttributes(xfc->display, window->handle, CWOverrideRedirect, &xswa);
			}

			/* if window is in maximized state, save and remove */
			if (xfc->_NET_WM_STATE_MAXIMIZED_VERT != None)
			{
				BYTE state;
				unsigned long nitems;
				unsigned long bytes;
				BYTE* prop;

				if (xf_GetWindowProperty(xfc, window->handle, xfc->_NET_WM_STATE, 255, &nitems, &bytes, &prop))
				{
					state = 0;

					while (nitems-- > 0)
					{
						if (((Atom*) prop)[nitems] == xfc->_NET_WM_STATE_MAXIMIZED_VERT)
							state |= 0x01;

						if (((Atom*) prop)[nitems] == xfc->_NET_WM_STATE_MAXIMIZED_HORZ)
							state |= 0x02;
					}

					if (state)
					{
						xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
						                   _NET_WM_STATE_REMOVE, xfc->_NET_WM_STATE_MAXIMIZED_VERT,
						                   0, 0);
						xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
						                   _NET_WM_STATE_REMOVE, xfc->_NET_WM_STATE_MAXIMIZED_HORZ,
						                   0, 0);
						xfc->savedMaximizedState = state;
					}

					XFree(prop);
				}
			}

			width = xfc->vscreen.area.right - xfc->vscreen.area.left + 1;
			height = xfc->vscreen.area.bottom - xfc->vscreen.area.top + 1;
			DEBUG_X11("X window move and resize %dx%d@%dx%d", startX, startY, width, height);
			xf_ResizeDesktopWindow(xfc, window, width, height);
			XMoveWindow(xfc->display, window->handle, startX, startY);
		}
		else
		{
			xf_SetWindowDecorations(xfc, window->handle, window->decorations);
			xf_ResizeDesktopWindow(xfc, window, width, height);
			XMoveWindow(xfc->display, window->handle, startX, startY);

			if (xfc->fullscreenMonitors.top)
			{
				xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
				                   _NET_WM_STATE_REMOVE,
				                   xfc->fullscreenMonitors.top, 0, 0);
			}

			/* restore maximized state, if the window was maximized before setting fullscreen */
			if (xfc->savedMaximizedState & 0x01)
			{
				xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
				                   _NET_WM_STATE_ADD, xfc->_NET_WM_STATE_MAXIMIZED_VERT,
				                   0, 0);
			}

			if (xfc->savedMaximizedState & 0x02)
			{
				xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
				                   _NET_WM_STATE_ADD, xfc->_NET_WM_STATE_MAXIMIZED_HORZ,
				                   0, 0);
			}

			xfc->savedMaximizedState = 0;
		}
	}
}
Esempio n. 19
0
static BOOL xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target)
{
	Atom type;
	int format;
	BYTE* data = NULL;
	BOOL has_data = FALSE;
	unsigned long length, bytes_left, dummy;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	if ((cb->request_index < 0) || (cb->format_mappings[cb->request_index].target_format != target))
	{
		DEBUG_X11_CLIPRDR("invalid target");
		xf_cliprdr_send_null_data_response(xfi);
		return FALSE;
	}

	XGetWindowProperty(xfi->display, xfi->drawable,
		cb->property_atom, 0, 0, 0, target,
		&type, &format, &length, &bytes_left, &data);

	DEBUG_X11_CLIPRDR("type=%d format=%d bytes=%d request_index=%d",
		(int) type, format, (int) bytes_left, cb->request_index);

	if (data)
	{
		XFree(data);
		data = NULL;
	}
	if (bytes_left <= 0 && !cb->incr_starts)
	{
		DEBUG_X11("no data");
	}
	else if (type == cb->incr_atom)
	{
		DEBUG_X11("INCR started");
		cb->incr_starts = TRUE;
		if (cb->incr_data)
		{
			free(cb->incr_data);
			cb->incr_data = NULL;
		}
		cb->incr_data_length = 0;
		/* Data will be followed in PropertyNotify event */
		has_data = TRUE;
	}
	else
	{
		if (bytes_left <= 0)
		{
			/* INCR finish */
			data = cb->incr_data;
			cb->incr_data = NULL;
			bytes_left = cb->incr_data_length;
			cb->incr_data_length = 0;
			cb->incr_starts = 0;
			DEBUG_X11("INCR finished");
			has_data = TRUE;
		}
		else if (XGetWindowProperty(xfi->display, xfi->drawable,
			cb->property_atom, 0, bytes_left, 0, target,
			&type, &format, &length, &dummy, &data) == Success)
		{
			if (cb->incr_starts)
			{
				bytes_left = length * format / 8;
				DEBUG_X11("%d bytes", (int)bytes_left);
				cb->incr_data = (BYTE*) realloc(cb->incr_data, cb->incr_data_length + bytes_left);
				CopyMemory(cb->incr_data + cb->incr_data_length, data, bytes_left);
				cb->incr_data_length += bytes_left;
				XFree(data);
				data = NULL;
			}
			has_data = TRUE;
		}
		else
		{
			DEBUG_X11_CLIPRDR("XGetWindowProperty failed");
		}
	}
	XDeleteProperty(xfi->display, xfi->drawable, cb->property_atom);

	xf_cliprdr_process_requested_data(xfi, has_data, data, (int) bytes_left);

	if (data)
		XFree(data);

	return TRUE;
}
Esempio n. 20
0
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width,
                                 int height)
{
	XEvent xevent;
	int input_mask;
	xfWindow* window;
	Window parentWindow;
	XClassHint* classHints;
	rdpSettings* settings;
	window = (xfWindow*) calloc(1, sizeof(xfWindow));

	if (!window)
		return NULL;

	settings = xfc->context.settings;
	parentWindow = (Window) xfc->context.settings->ParentWindowId;
	window->width = width;
	window->height = height;
	window->decorations = xfc->decorations;
	window->is_mapped = FALSE;
	window->is_transient = FALSE;
	window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
	                               xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height,
	                               0, xfc->depth, InputOutput, xfc->visual,
	                               CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
	                               CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
	window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR),
	                         (S_IREAD | S_IWRITE));

	if (window->shmid < 0)
	{
		DEBUG_X11("xf_CreateDesktopWindow: failed to get access to shared memory - shmget()\n");
	}
	else
	{
		void* mem;
		ftruncate(window->shmid, sizeof(window->handle));
		mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED,
		           window->shmid, 0);

		if (mem == MAP_FAILED)
		{
			DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n");
		}
		else
		{
			window->xfwin = mem;
			*window->xfwin = window->handle;
		}
	}

	classHints = XAllocClassHint();

	if (classHints)
	{
		classHints->res_name = "xfreerdp";

		if (xfc->context.settings->WmClass)
			classHints->res_class = xfc->context.settings->WmClass;
		else
			classHints->res_class = "xfreerdp";

		XSetClassHint(xfc->display, window->handle, classHints);
		XFree(classHints);
	}

	xf_ResizeDesktopWindow(xfc, window, width, height);
	xf_SetWindowDecorations(xfc, window->handle, window->decorations);
	xf_SetWindowPID(xfc, window->handle, 0);
	input_mask =
	    KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
	    VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
	    PointerMotionMask | ExposureMask | PropertyChangeMask;

	if (xfc->grab_keyboard)
		input_mask |= EnterWindowMask | LeaveWindowMask;

	XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL,
	                32,
	                PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));

	if (parentWindow)
		XReparentWindow(xfc->display, window->handle, parentWindow, 0, 0);

	XSelectInput(xfc->display, window->handle, input_mask);
	XClearWindow(xfc->display, window->handle);
	xf_SetWindowTitleText(xfc, window->handle, name);
	XMapWindow(xfc->display, window->handle);
	xf_input_init(xfc, window->handle);

	/*
	 * NOTE: This must be done here to handle reparenting the window,
	 * so that we don't miss the event and hang waiting for the next one
	 */
	do
	{
		XMaskEvent(xfc->display, VisibilityChangeMask, &xevent);
	}
	while (xevent.type != VisibilityNotify);

	/*
	 * The XCreateWindow call will start the window in the upper-left corner of our current
	 * monitor instead of the upper-left monitor for remote app mode (which uses all monitors).
	 * This extra call after the window is mapped will position the login window correctly
	 */
	if (xfc->context.settings->RemoteApplicationMode)
	{
		XMoveWindow(xfc->display, window->handle, 0, 0);
	}
	else if (settings->DesktopPosX != UINT32_MAX && settings->DesktopPosY != UINT32_MAX)
	{
		XMoveWindow(xfc->display, window->handle, settings->DesktopPosX,
		            settings->DesktopPosY);
	}

	window->floatbar = xf_floatbar_new(xfc, window->handle, name, settings->Floatbar);
	return window;
}
Esempio n. 21
0
static void xf_cliprdr_process_cb_data_response_event(xfInfo* xfi, RDP_CB_DATA_RESPONSE_EVENT* event)
{
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	DEBUG_X11("size=%d", event->size);

	if (cb->respond == NULL)
	{
		DEBUG_X11("unexpected data");
		return;
	}

	if (event->size == 0)
	{
		cb->respond->xselection.property = None;
	}
	else
	{
		if (cb->data)
		{
			xfree(cb->data);
			cb->data = NULL;
		}
		switch (cb->data_format)
		{
			case CB_FORMAT_RAW:
			case CB_FORMAT_PNG:
			case CB_FORMAT_JPEG:
			case CB_FORMAT_GIF:
				cb->data = event->data;
				cb->data_length = event->size;
				event->data = NULL;
				event->size = 0;
				break;

			case CB_FORMAT_TEXT:
				xf_cliprdr_process_text(cb, event->data, event->size);
				break;

			case CB_FORMAT_UNICODETEXT:
				xf_cliprdr_process_unicodetext(cb, event->data, event->size);
				break;

			case CB_FORMAT_DIB:
				xf_cliprdr_process_dib(cb, event->data, event->size);
				break;

			case CB_FORMAT_HTML:
				xf_cliprdr_process_html(cb, event->data, event->size);
				break;

			default:
				cb->respond->xselection.property = None;
				break;
		}
		xf_cliprdr_provide_data(xfi, cb->respond);
	}

	XSendEvent(xfi->display, cb->respond->xselection.requestor,
		0, 0, cb->respond);
	XFlush(xfi->display);
	xfree(cb->respond);
	cb->respond = NULL;
}
Esempio n. 22
0
boolean xf_event_process(freerdp* instance, XEvent* event)
{
	boolean app = False;
	boolean status = True;
	xfInfo* xfi = GET_XFI(instance);

	if (xfi->remote_app == True)
	{
		app = True;
	}
	else
	{
		if (event->xany.window != xfi->window->handle)
			app = True;
	}


	if (event->type != MotionNotify)
		DEBUG_X11("%s Event: wnd=0x%04X", X11_EVENT_STRINGS[event->type], (uint32) event->xany.window);

	switch (event->type)
	{
		case Expose:
			status = xf_event_Expose(xfi, event, app);
			break;

		case VisibilityNotify:
			status = xf_event_VisibilityNotify(xfi, event, app);
			break;

		case MotionNotify:
			status = xf_event_MotionNotify(xfi, event, app);
			break;

		case ButtonPress:
			status = xf_event_ButtonPress(xfi, event, app);
			break;

		case ButtonRelease:
			status = xf_event_ButtonRelease(xfi, event, app);
			break;

		case KeyPress:
			status = xf_event_KeyPress(xfi, event, app);
			break;

		case KeyRelease:
			status = xf_event_KeyRelease(xfi, event, app);
			break;

		case FocusIn:
			status = xf_event_FocusIn(xfi, event, app);
			break;

		case FocusOut:
			status = xf_event_FocusOut(xfi, event, app);
			break;

		case EnterNotify:
			status = xf_event_EnterNotify(xfi, event, app);
			break;

		case LeaveNotify:
			status = xf_event_LeaveNotify(xfi, event, app);
			break;

		case NoExpose:
			break;

		case GraphicsExpose:
			break;

		case ConfigureNotify:
			status = xf_event_ConfigureNotify(xfi, event, app);
			break;

		case MapNotify:
			status = xf_event_MapNotify(xfi, event, app);
			break;

		case ReparentNotify:
			break;

		case MappingNotify:
			status = xf_event_MappingNotify(xfi, event, app);
			break;

		case ClientMessage:
			status = xf_event_ClientMessage(xfi, event, app);
			break;

		default:
			DEBUG_X11("xf_event_process unknown event %d", event->type);
			break;
	}

	return status;
}
Esempio n. 23
0
boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
{
	int i;
	int fmt;
	Atom type;
	uint32 format;
	XEvent* respond;
	uint32 alt_format;
	uint8* data = NULL;
	boolean delay_respond;
	unsigned long len, bytes_left;
	clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;

	DEBUG_X11("target=%d", (int)xevent->xselectionrequest.target);

	if (xevent->xselectionrequest.owner != xfi->window->handle)
	{
		DEBUG_X11("not owner");
		return False;
	}

	delay_respond = False;
	respond = xnew(XEvent);
	respond->xselection.property = None;
	respond->xselection.type = SelectionNotify;
	respond->xselection.display = xevent->xselectionrequest.display;
	respond->xselection.requestor = xevent->xselectionrequest.requestor;
	respond->xselection.selection = xevent->xselectionrequest.selection;
	respond->xselection.target = xevent->xselectionrequest.target;
	respond->xselection.time = xevent->xselectionrequest.time;
	if (xevent->xselectionrequest.target == cb->targets[0]) /* TIMESTAMP */
	{
		/* TODO */
	}
	else if (xevent->xselectionrequest.target == cb->targets[1]) /* TARGETS */
	{
		/* Someone else requests our available formats */
		respond->xselection.property = xevent->xselectionrequest.property;
		xf_cliprdr_provide_targets(xfi, respond);
	}
	else
	{
		i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target);
		if (i >= 0 && xevent->xselectionrequest.requestor != xfi->window->handle)
		{
			format = cb->format_mappings[i].format_id;
			alt_format = format;
			if (format == CB_FORMAT_RAW)
			{
				if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor,
					cb->property_atom, 0, 4, 0, XA_INTEGER,
					&type, &fmt, &len, &bytes_left, &data) != Success)
				{
					DEBUG_X11("XGetWindowProperty failed");
				}
				if (data)
				{
					memcpy(&alt_format, data, 4);
					XFree(data);
				}
			}
			DEBUG_X11("provide format 0x%04x alt_format 0x%04x", format, alt_format);
			if (cb->data != 0 &&
				format == cb->data_format &&
				alt_format == cb->data_alt_format)
			{
				/* Cached clipboard data available. Send it now */
				respond->xselection.property = xevent->xselectionrequest.property;
				xf_cliprdr_provide_data(xfi, respond);
			}
			else if (cb->respond)
			{
				DEBUG_X11("duplicated request");
			}
			else
			{
				/**
				 * Send clipboard data request to the server.
				 * Response will be postponed after receiving the data
				 */
				if (cb->data)
				{
					xfree(cb->data);
					cb->data = NULL;
				}
				respond->xselection.property = xevent->xselectionrequest.property;
				cb->respond = respond;
				cb->data_format = format;
				cb->data_alt_format = alt_format;
				delay_respond = True;

				xf_cliprdr_send_data_request(xfi, alt_format);
			}
		}
	}

	if (!delay_respond)
	{
		XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond);
		XFlush(xfi->display);
		xfree(respond);
	}

	return True;
}
Esempio n. 24
0
static int
run_xfreerdp(xfInfo * xfi)
{
	rdpInst * inst;
	void * read_fds[32];
	void * write_fds[32];
	int read_count;
	int write_count;
	int index;
	int sck;
	int max_sck;
	fd_set rfds;
	fd_set wfds;
	RD_EVENT * event;

	/* create an instance of the library */
	inst = freerdp_new(xfi->settings);
	if (inst == NULL)
	{
		printf("run_xfreerdp: freerdp_new failed\n");
		return XF_EXIT_MEMORY;
	}
	if ((inst->version != FREERDP_INTERFACE_VERSION) ||
	    (inst->size != sizeof(rdpInst)))
	{
		printf("run_xfreerdp: freerdp_new size, version / size do not "
		       "match expecting v %d s %d got v %d s %d\n",
		       FREERDP_INTERFACE_VERSION, (int)sizeof(rdpInst),
		       inst->version, inst->size);
		return XF_EXIT_PROTOCOL;
	}
	xfi->inst = inst;
	SET_XFI(inst, xfi);
	if (xf_pre_connect(xfi) != 0)
	{
		printf("run_xfreerdp: xf_pre_connect failed\n");
		return XF_EXIT_CONN_FAILED;
	}
	if (freerdp_chanman_pre_connect(xfi->chan_man, inst) != 0)
	{
		printf("run_xfreerdp: freerdp_chanman_pre_connect failed\n");
		return XF_EXIT_CONN_FAILED;
	}

	xf_kb_init(xfi->display, xfi->keyboard_layout_id);
	xf_kb_inst_init(xfi);
	printf("keyboard_layout: 0x%X\n", inst->settings->keyboard_layout);

	/* call connect */
	if (inst->rdp_connect(inst) != 0)
	{
		printf("run_xfreerdp: inst->rdp_connect failed\n");
		return XF_EXIT_CONN_FAILED;
	}
	if (freerdp_chanman_post_connect(xfi->chan_man, inst) != 0)
	{
		printf("run_xfreerdp: freerdp_chanman_post_connect failed\n");
		return XF_EXIT_CONN_FAILED;
	}
	if (xf_post_connect(xfi) != 0)
	{
		printf("run_xfreerdp: xf_post_connect failed\n");
		return XF_EXIT_CONN_FAILED;
	}
	xf_video_init(xfi);
	xf_decode_init(xfi);

	/* program main loop */
	while (1)
	{
		read_count = 0;
		write_count = 0;
		/* get libfreerdp fds */
		if (inst->rdp_get_fds(inst, read_fds, &read_count, write_fds, &write_count) != 0)
		{
			printf("run_xfreerdp: inst->rdp_get_fds failed\n");
			break;
		}
		/* get x fds */
		if (xf_get_fds(xfi, read_fds, &read_count, write_fds, &write_count) != 0)
		{
			printf("run_xfreerdp: xf_get_fds failed\n");
			break;
		}
		/* get channel fds */
		if (freerdp_chanman_get_fds(xfi->chan_man, inst, read_fds, &read_count, write_fds, &write_count) != 0)
		{
			printf("run_xfreerdp: freerdp_chanman_get_fds failed\n");
			break;
		}
		max_sck = 0;
		/* setup read fds */
		FD_ZERO(&rfds);
		for (index = 0; index < read_count; index++)
		{
			sck = (int)(long) (read_fds[index]);
			if (sck > max_sck)
				max_sck = sck;
			FD_SET(sck, &rfds);
		}
		/* setup write fds */
		FD_ZERO(&wfds);
		for (index = 0; index < write_count; index++)
		{
			sck = (int)(long) (write_fds[index]);
			if (sck > max_sck)
				max_sck = sck;
			FD_SET(sck, &wfds);
		}
		/* exit if nothing to do */
		if (max_sck == 0)
		{
			printf("run_xfreerdp: max_sck is zero\n");
			break;
		}
		/* do the wait */
		if (select(max_sck + 1, &rfds, &wfds, NULL, NULL) == -1)
		{
			/* these are not really errors */
			if (!((errno == EAGAIN) ||
				(errno == EWOULDBLOCK) ||
				(errno == EINPROGRESS) ||
				(errno == EINTR))) /* signal occurred */
			{
				printf("run_xfreerdp: select failed\n");
				break;
			}
		}
		/* check the libfreerdp fds */
		if (inst->rdp_check_fds(inst) != 0)
		{
			printf("run_xfreerdp: inst->rdp_check_fds failed\n");
			break;
		}
		/* check x fds */
		if (xf_check_fds(xfi) != 0)
		{
			/* xfreerdp is usually terminated by this failing because the X windows has been closed */
			DEBUG_X11("xf_check_fds failed");
			break;
		}
		/* check channel fds */
		if (freerdp_chanman_check_fds(xfi->chan_man, inst) != 0)
		{
			printf("run_xfreerdp: freerdp_chanman_check_fds failed\n");
			break;
		}
		/* check channel event */
		event = freerdp_chanman_pop_event(xfi->chan_man);
		if (event)
		{
			switch (event->event_type)
			{
				case RD_EVENT_TYPE_VIDEO_FRAME:
					xf_video_process_frame(xfi, (RD_VIDEO_FRAME_EVENT *) event);
					break;
				case RD_EVENT_TYPE_REDRAW:
					xf_handle_redraw_event(xfi, (RD_REDRAW_EVENT *) event);
					break;
				default:
					printf("run_xfreerdp: unknown event type %d\n", event->event_type);
					break;
			}
			freerdp_chanman_free_event(xfi->chan_man, event);
		}
	}

	g_disconnect_reason = inst->disc_reason;

	/* cleanup */
	xf_decode_uninit(xfi);
	xf_video_uninit(xfi);
	freerdp_chanman_close(xfi->chan_man, inst);
	inst->rdp_disconnect(inst);
	freerdp_free(inst);
	xf_uninit(xfi);
	return 0;
}
Esempio n. 25
0
BOOL xf_event_process(freerdp* instance, XEvent* event)
{
	BOOL status = TRUE;
	xfAppWindow* appWindow;
	xfContext* xfc = (xfContext*) instance->context;

	if (xfc->remote_app)
	{
		appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);

		if (appWindow)
		{
			/* Update "current" window for cursor change orders */
			xfc->appWindow = appWindow;

			if (xf_event_suppress_events(xfc, appWindow, event))
				return TRUE;
		}
	}

	xf_event_execute_action_script(xfc, event);

	if (event->type != MotionNotify)
		DEBUG_X11("%s Event(%d): wnd=0x%08lX", X11_EVENT_STRINGS[event->type],
		          event->type, (unsigned long) event->xany.window);

	switch (event->type)
	{
		case Expose:
			status = xf_event_Expose(xfc, event, xfc->remote_app);
			break;

		case VisibilityNotify:
			status = xf_event_VisibilityNotify(xfc, event, xfc->remote_app);
			break;

		case MotionNotify:
			status = xf_event_MotionNotify(xfc, event, xfc->remote_app);
			break;

		case ButtonPress:
			status = xf_event_ButtonPress(xfc, event, xfc->remote_app);
			break;

		case ButtonRelease:
			status = xf_event_ButtonRelease(xfc, event, xfc->remote_app);
			break;

		case KeyPress:
			status = xf_event_KeyPress(xfc, event, xfc->remote_app);
			break;

		case KeyRelease:
			status = xf_event_KeyRelease(xfc, event, xfc->remote_app);
			break;

		case FocusIn:
			status = xf_event_FocusIn(xfc, event, xfc->remote_app);
			break;

		case FocusOut:
			status = xf_event_FocusOut(xfc, event, xfc->remote_app);
			break;

		case EnterNotify:
			status = xf_event_EnterNotify(xfc, event, xfc->remote_app);
			break;

		case LeaveNotify:
			status = xf_event_LeaveNotify(xfc, event, xfc->remote_app);
			break;

		case NoExpose:
			break;

		case GraphicsExpose:
			break;

		case ConfigureNotify:
			status = xf_event_ConfigureNotify(xfc, event, xfc->remote_app);
			break;

		case MapNotify:
			status = xf_event_MapNotify(xfc, event, xfc->remote_app);
			break;

		case UnmapNotify:
			status = xf_event_UnmapNotify(xfc, event, xfc->remote_app);
			break;

		case ReparentNotify:
			break;

		case MappingNotify:
			status = xf_event_MappingNotify(xfc, event, xfc->remote_app);
			break;

		case ClientMessage:
			status = xf_event_ClientMessage(xfc, event, xfc->remote_app);
			break;

		case PropertyNotify:
			status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
			break;
	}

	if (!xfc->remote_app)
	{
		xf_cliprdr_handle_xevent(xfc, event);
	}

	xf_input_handle_event(xfc, event);
	XSync(xfc->display, FALSE);
	return status;
}
Esempio n. 26
0
/* Returns "true" on errors or other reasons to not continue normal operation */
static int
process_params(xfInfo * xfi, int argc, char ** argv, int * pindex)
{
	rdpSet * settings;
	rdpKeyboardLayout * layouts;
	char * p;
	RD_PLUGIN_DATA plugin_data[MAX_PLUGIN_DATA + 1];
	int index;
	int i, j;
	struct passwd * pw;
	int num_extensions;
	int rv;

	set_default_params(xfi);
	settings = xfi->settings;
	num_extensions = 0;
	p = getlogin();
	i = sizeof(settings->username) - 1;
	if (p != 0)
	{
		strncpy(settings->username, p, i);
	}
	else
	{
		pw = getpwuid(getuid());
		if (pw != 0)
		{
			if (pw->pw_name != 0)
			{
				strncpy(settings->username, pw->pw_name, i);
			}
		}
	}

	if (argc < *pindex + 1)
	{
		if (*pindex == 1)
			printf("no parameters specified\n");
		return 1;
	}
	while (*pindex < argc)
	{
		if (strcmp("-a", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing server depth\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			settings->server_depth = atoi(argv[*pindex]);
		}
		else if (strcmp("-u", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing username\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->username, argv[*pindex], sizeof(settings->username) - 1);
			settings->username[sizeof(settings->username) - 1] = 0;
		}
		else if (strcmp("-p", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing password\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->password, argv[*pindex], sizeof(settings->password) - 1);
			settings->password[sizeof(settings->password) - 1] = 0;
			settings->autologin = 1;

			/*
			 * Overwrite original password which could be revealed by a simple "ps aux" command.
			 * This approach won't hide the password length, but it is better than nothing.
			 */

			memset(argv[*pindex], '*', strlen(argv[*pindex]));
		}
		else if (strcmp("-d", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing domain\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->domain, argv[*pindex], sizeof(settings->domain) - 1);
			settings->domain[sizeof(settings->domain) - 1] = 0;
		}
		else if (strcmp("-k", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing keyboard layout ID\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			sscanf(argv[*pindex], "%X", &(xfi->keyboard_layout_id));
			DEBUG_X11("keyboard layout ID: %X", xfi->keyboard_layout_id);
		}
		else if (strcmp("-K", argv[*pindex]) == 0)
		{
			xfi->grab_keyboard = 0;
		}
		else if (strcmp("--kbd-list", argv[*pindex]) == 0)
		{
			layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD);
			printf("\nKeyboard Layouts\n");
			for (i = 0; layouts[i].code; i++)
				printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name);
			free(layouts);

			layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
			printf("\nKeyboard Layout Variants\n");
			for (i = 0; layouts[i].code; i++)
				printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name);
			free(layouts);

			layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME);
			printf("\nKeyboard Input Method Editors (IMEs)\n");
			for (i = 0; layouts[i].code; i++)
				printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name);
			free(layouts);

			return 1;
		}
		else if (strcmp("-s", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing shell\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->shell, argv[*pindex], sizeof(settings->shell) - 1);
			settings->shell[sizeof(settings->shell) - 1] = 0;
		}
		else if (strcmp("-c", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing directory\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->directory, argv[*pindex], sizeof(settings->directory) - 1);
			settings->directory[sizeof(settings->directory) - 1] = 0;
		}
		else if (strcmp("-g", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing width\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			settings->width = strtol(argv[*pindex], &p, 10);
			if (*p == 'x')
			{
				settings->height = strtol(p + 1, &p, 10);
			}
			if (*p == '%')
			{
				xfi->percentscreen = settings->width;
			}
		}
		else if (strcmp("-t", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing port number\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			settings->tcp_port_rdp = atoi(argv[*pindex]);
		}
		else if (strcmp("-T", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing window title\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(xfi->window_title, argv[*pindex], sizeof(xfi->window_title) - 1);
			xfi->window_title[sizeof(xfi->window_title) - 1] = 0;
		}
		else if (strcmp("-n", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing hostname\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->hostname, argv[*pindex], sizeof(settings->hostname) - 1);
			settings->hostname[sizeof(settings->hostname) - 1] = 0;
		}
		else if (strcmp("-o", argv[*pindex]) == 0)
		{
			settings->console_audio = 1;
		}
		else if (strcmp("-0", argv[*pindex]) == 0)
		{
			settings->console_session = 1;
		}
		else if (strcmp("-z", argv[*pindex]) == 0)
		{
			settings->bulk_compression = 1;
		}
		else if (strcmp("--gdi", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing GDI rendering\n");
				return 1;
			}
			if (strncmp("sw", argv[*pindex], 1) == 0) /* Software */
			{
				settings->software_gdi = 1;
			}
			else if (strncmp("hw", argv[*pindex], 1) == 0) /* Hardware */
			{
				settings->software_gdi = 0;
			}
			else
			{
				printf("unknown GDI rendering\n");
				return 1;
			}
		}
		else if (strcmp("--no-osb", argv[*pindex]) == 0)
		{
			settings->off_screen_bitmaps = 0;
		}
		else if (strcmp("--rfx", argv[*pindex]) == 0)
		{
			settings->rfx_flags = 1;
			settings->ui_decode_flags = 1;
			settings->use_frame_ack = 0;
			settings->server_depth = 32;
			settings->performanceflags = PERF_FLAG_NONE;
			xfi->codec = XF_CODEC_REMOTEFX;
		}
		else if (strcmp("--app", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing application name\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			strncpy(settings->app_name, argv[*pindex], sizeof(settings->app_name) - 1);
			settings->app_name[sizeof(settings->app_name) - 1] = 0;
			settings->remote_app = 1;
		}
#ifdef HAVE_XV
		else if (strcmp("--xv-port", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			xfi->xv_port = atoi(argv[*pindex]);
		}
#endif
		else if (strcmp("-f", argv[*pindex]) == 0)
		{
			xfi->fullscreen = xfi->fs_toggle = 1;
			printf("full screen option\n");
		}
		else if (strcmp("-D", argv[*pindex]) == 0)
		{
			xfi->decoration = 0;
		}
		else if (strcmp("-x", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing performance flag\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			if (strncmp("m", argv[*pindex], 1) == 0) /* modem */
			{
				settings->performanceflags = PERF_DISABLE_WALLPAPER |
					PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
					PERF_DISABLE_THEMING;
			}
			else if (strncmp("b", argv[*pindex], 1) == 0) /* broadband */
			{
				settings->performanceflags = PERF_DISABLE_WALLPAPER;
			}
			else if (strncmp("l", argv[*pindex], 1) == 0) /* lan */
			{
				settings->performanceflags = PERF_FLAG_NONE;
			}
			else
			{
				settings->performanceflags = strtol(argv[*pindex], 0, 16);
			}
		} else if (strcmp("-X", argv[*pindex]) == 0) {
			*pindex = *pindex + 1;

			if (*pindex == argc) {
				printf("missing XID\n");
				exit(XF_EXIT_WRONG_PARAM);
			}

			xfi->embed = strtoul(argv[*pindex], NULL, 16);
			if (!xfi->embed) {
				printf("bad XID\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
		}
#ifndef DISABLE_TLS
		else if (strcmp("--no-rdp", argv[*pindex]) == 0)
		{
			settings->rdp_security = 0;
		}
		else if (strcmp("--no-tls", argv[*pindex]) == 0)
		{
			settings->tls_security = 0;
		}
		else if (strcmp("--no-nla", argv[*pindex]) == 0)
		{
			settings->nla_security = 0;
		}
		else if (strcmp("--sec", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing protocol security\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			if (strncmp("rdp", argv[*pindex], 1) == 0) /* Standard RDP */
			{
				settings->rdp_security = 1;
				settings->tls_security = 0;
				settings->nla_security = 0;
			}
			else if (strncmp("tls", argv[*pindex], 1) == 0) /* TLS */
			{
				settings->rdp_security = 0;
				settings->tls_security = 1;
				settings->nla_security = 0;
			}
			else if (strncmp("nla", argv[*pindex], 1) == 0) /* NLA */
			{
				settings->rdp_security = 0;
				settings->tls_security = 0;
				settings->nla_security = 1;
			}
			else
			{
				printf("unknown protocol security\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
		}
#endif
		else if (strcmp("--plugin", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing plugin name\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			index = *pindex;
			memset(plugin_data, 0, sizeof(plugin_data));
			if (*pindex < argc - 1 && strcmp("--data", argv[*pindex + 1]) == 0)
			{
				*pindex = *pindex + 2;
				i = 0;
				while (*pindex < argc && strcmp("--", argv[*pindex]) != 0 && i < MAX_PLUGIN_DATA)
				{
					plugin_data[i].size = sizeof(RD_PLUGIN_DATA);
					for (j = 0, p = argv[*pindex]; j < 4 && p != NULL; j++)
					{
						plugin_data[i].data[j] = p;
						if (j < 3)
						{
							p = strchr(plugin_data[i].data[j], ':');
							if (p != NULL)
								*p++ = 0;
						}
					}
					*pindex = *pindex + 1;
					i++;
				}
			}
			rv = freerdp_chanman_load_plugin(xfi->chan_man, settings, argv[index], plugin_data);
			if (rv)
				exit(XF_EXIT_WRONG_PARAM);
		}
		else if (strcmp("--ext", argv[*pindex]) == 0)
		{
			*pindex = *pindex + 1;
			if (*pindex == argc)
			{
				printf("missing extension name\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			if (num_extensions >= sizeof(settings->extensions) / sizeof(struct rdp_ext_set))
			{
				printf("maximum extensions reached\n");
				exit(XF_EXIT_WRONG_PARAM);
			}
			index = *pindex;
			snprintf(settings->extensions[num_extensions].name,
				sizeof(settings->extensions[num_extensions].name),
				"%s", argv[index]);
			settings->extensions[num_extensions].data = NULL;
			if (*pindex < argc - 1 && strcmp("--data", argv[*pindex + 1]) == 0)
			{
				*pindex = *pindex + 2;
				settings->extensions[num_extensions].data = argv[*pindex];
				i = 0;
				while (*pindex < argc && strcmp("--", argv[*pindex]) != 0)
				{
					*pindex = *pindex + 1;
					i++;
				}
			}
			num_extensions++;
		}
		else if ((strcmp("-h", argv[*pindex]) == 0) || strcmp("--help", argv[*pindex]) == 0)
		{
			out_args();
			return 1;
		}
		else if (strcmp("--version", argv[*pindex]) == 0)
		{
			printf("This is FreeRDP version %s\n", PACKAGE_VERSION);
			return 1;
		}
		else if (argv[*pindex][0] != '-')
		{
			settings->server[sizeof(settings->server) - 1] = 0;
			if (argv[*pindex][0] == '[' && (p = strchr(argv[*pindex], ']'))
				&& (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
			{
				/* Either "[...]" or "[...]:..." with at most one : after the brackets */
				strncpy(settings->server, argv[*pindex] + 1, sizeof(settings->server) - 1);
				if ((p = strchr(settings->server, ']')))
				{
					*p = 0;
					if (p[1] == ':')
						settings->tcp_port_rdp = atoi(p + 2);
				}
			}
			else
			{
				/* Port number is cut off and used if exactly one : in the string */
				strncpy(settings->server, argv[*pindex], sizeof(settings->server) - 1);
				if ((p = strchr(settings->server, ':')) && !strchr(p + 1, ':'))
				{
					*p = 0;
					settings->tcp_port_rdp = atoi(p + 1);
				}
			}
			/* server is the last argument for the current session. arguments
			   followed will be parsed for the next session. */
			*pindex = *pindex + 1;

			return 0;
		}
		else
		{
			printf("invalid option: %s\n", argv[*pindex]);
			exit(XF_EXIT_WRONG_PARAM);
		}
		*pindex = *pindex + 1;
	}
	printf("missing server name\n");
	exit(XF_EXIT_WRONG_PARAM);
}