Blame client/X11/xf_event.c

Packit Service fa4841
/**
Packit Service fa4841
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit Service fa4841
 * X11 Event Handling
Packit Service fa4841
 *
Packit Service fa4841
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit Service fa4841
 *
Packit Service fa4841
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit Service fa4841
 * you may not use this file except in compliance with the License.
Packit Service fa4841
 * You may obtain a copy of the License at
Packit Service fa4841
 *
Packit Service fa4841
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit Service fa4841
 *
Packit Service fa4841
 * Unless required by applicable law or agreed to in writing, software
Packit Service fa4841
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit Service fa4841
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service fa4841
 * See the License for the specific language governing permissions and
Packit Service fa4841
 * limitations under the License.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_CONFIG_H
Packit Service fa4841
#include "config.h"
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <X11/Xlib.h>
Packit Service fa4841
#include <X11/Xutil.h>
Packit Service fa4841
Packit Service fa4841
#include <freerdp/log.h>
Packit Service fa4841
#include <freerdp/locale/keyboard.h>
Packit Service fa4841
Packit Service fa4841
#include "xf_rail.h"
Packit Service fa4841
#include "xf_window.h"
Packit Service fa4841
#include "xf_cliprdr.h"
Packit Service fa4841
#include "xf_disp.h"
Packit Service fa4841
#include "xf_input.h"
Packit Service fa4841
#include "xf_gfx.h"
Packit Service fa4841
Packit Service fa4841
#include "xf_event.h"
Packit Service fa4841
#include "xf_input.h"
Packit Service fa4841
Packit Service fa4841
#define TAG CLIENT_TAG("x11")
Packit Service fa4841
Packit Service b1ea74
#define CLAMP_COORDINATES(x, y) \
Packit Service b1ea74
	if (x < 0)                  \
Packit Service b1ea74
		x = 0;                  \
Packit Service b1ea74
	if (y < 0)                  \
Packit Service b1ea74
	y = 0
Packit Service fa4841
Packit Service fa4841
static const char* x11_event_string(int event)
Packit Service fa4841
{
Packit Service fa4841
	switch (event)
Packit Service fa4841
	{
Packit Service fa4841
		case KeyPress:
Packit Service fa4841
			return "KeyPress";
Packit Service fa4841
Packit Service fa4841
		case KeyRelease:
Packit Service fa4841
			return "KeyRelease";
Packit Service fa4841
Packit Service fa4841
		case ButtonPress:
Packit Service fa4841
			return "ButtonPress";
Packit Service fa4841
Packit Service fa4841
		case ButtonRelease:
Packit Service fa4841
			return "ButtonRelease";
Packit Service fa4841
Packit Service fa4841
		case MotionNotify:
Packit Service fa4841
			return "MotionNotify";
Packit Service fa4841
Packit Service fa4841
		case EnterNotify:
Packit Service fa4841
			return "EnterNotify";
Packit Service fa4841
Packit Service fa4841
		case LeaveNotify:
Packit Service fa4841
			return "LeaveNotify";
Packit Service fa4841
Packit Service fa4841
		case FocusIn:
Packit Service fa4841
			return "FocusIn";
Packit Service fa4841
Packit Service fa4841
		case FocusOut:
Packit Service fa4841
			return "FocusOut";
Packit Service fa4841
Packit Service fa4841
		case KeymapNotify:
Packit Service fa4841
			return "KeymapNotify";
Packit Service fa4841
Packit Service fa4841
		case Expose:
Packit Service fa4841
			return "Expose";
Packit Service fa4841
Packit Service fa4841
		case GraphicsExpose:
Packit Service fa4841
			return "GraphicsExpose";
Packit Service fa4841
Packit Service fa4841
		case NoExpose:
Packit Service fa4841
			return "NoExpose";
Packit Service fa4841
Packit Service fa4841
		case VisibilityNotify:
Packit Service fa4841
			return "VisibilityNotify";
Packit Service fa4841
Packit Service fa4841
		case CreateNotify:
Packit Service fa4841
			return "CreateNotify";
Packit Service fa4841
Packit Service fa4841
		case DestroyNotify:
Packit Service fa4841
			return "DestroyNotify";
Packit Service fa4841
Packit Service fa4841
		case UnmapNotify:
Packit Service fa4841
			return "UnmapNotify";
Packit Service fa4841
Packit Service fa4841
		case MapNotify:
Packit Service fa4841
			return "MapNotify";
Packit Service fa4841
Packit Service fa4841
		case MapRequest:
Packit Service fa4841
			return "MapRequest";
Packit Service fa4841
Packit Service fa4841
		case ReparentNotify:
Packit Service fa4841
			return "ReparentNotify";
Packit Service fa4841
Packit Service fa4841
		case ConfigureNotify:
Packit Service fa4841
			return "ConfigureNotify";
Packit Service fa4841
Packit Service fa4841
		case ConfigureRequest:
Packit Service fa4841
			return "ConfigureRequest";
Packit Service fa4841
Packit Service fa4841
		case GravityNotify:
Packit Service fa4841
			return "GravityNotify";
Packit Service fa4841
Packit Service fa4841
		case ResizeRequest:
Packit Service fa4841
			return "ResizeRequest";
Packit Service fa4841
Packit Service fa4841
		case CirculateNotify:
Packit Service fa4841
			return "CirculateNotify";
Packit Service fa4841
Packit Service fa4841
		case CirculateRequest:
Packit Service fa4841
			return "CirculateRequest";
Packit Service fa4841
Packit Service fa4841
		case PropertyNotify:
Packit Service fa4841
			return "PropertyNotify";
Packit Service fa4841
Packit Service fa4841
		case SelectionClear:
Packit Service fa4841
			return "SelectionClear";
Packit Service fa4841
Packit Service fa4841
		case SelectionRequest:
Packit Service fa4841
			return "SelectionRequest";
Packit Service fa4841
Packit Service fa4841
		case SelectionNotify:
Packit Service fa4841
			return "SelectionNotify";
Packit Service fa4841
Packit Service fa4841
		case ColormapNotify:
Packit Service fa4841
			return "ColormapNotify";
Packit Service fa4841
Packit Service fa4841
		case ClientMessage:
Packit Service fa4841
			return "ClientMessage";
Packit Service fa4841
Packit Service fa4841
		case MappingNotify:
Packit Service fa4841
			return "MappingNotify";
Packit Service fa4841
Packit Service fa4841
		case GenericEvent:
Packit Service fa4841
			return "GenericEvent";
Packit Service fa4841
Packit Service fa4841
		default:
Packit Service fa4841
			return "UNKNOWN";
Packit Service fa4841
	};
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#ifdef WITH_DEBUG_X11
Packit Service fa4841
#define DEBUG_X11(...) WLog_DBG(TAG, __VA_ARGS__)
Packit Service fa4841
#else
Packit Service b1ea74
#define DEBUG_X11(...) \
Packit Service b1ea74
	do                 \
Packit Service b1ea74
	{                  \
Packit Service b1ea74
	} while (0)
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
BOOL xf_event_action_script_init(xfContext* xfc)
Packit Service fa4841
{
Packit Service fa4841
	char* xevent;
Packit Service fa4841
	FILE* actionScript;
Packit Service fa4841
	char buffer[1024] = { 0 };
Packit Service fa4841
	char command[1024] = { 0 };
Packit Service fa4841
	xfc->xevents = ArrayList_New(TRUE);
Packit Service fa4841
Packit Service fa4841
	if (!xfc->xevents)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	ArrayList_Object(xfc->xevents)->fnObjectFree = free;
Packit Service fa4841
	sprintf_s(command, sizeof(command), "%s xevent", xfc->context.settings->ActionScript);
Packit Service fa4841
	actionScript = popen(command, "r");
Packit Service fa4841
Packit Service fa4841
	if (!actionScript)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	while (fgets(buffer, sizeof(buffer), actionScript))
Packit Service fa4841
	{
Packit Service b1ea74
		char* context = NULL;
Packit Service b1ea74
		strtok_s(buffer, "\n", &context);
Packit Service fa4841
		xevent = _strdup(buffer);
Packit Service fa4841
Packit Service fa4841
		if (!xevent || ArrayList_Add(xfc->xevents, xevent) < 0)
Packit Service fa4841
		{
Packit Service fa4841
			pclose(actionScript);
Packit Service fa4841
			ArrayList_Free(xfc->xevents);
Packit Service fa4841
			xfc->xevents = NULL;
Packit Service fa4841
			return FALSE;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	pclose(actionScript);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
void xf_event_action_script_free(xfContext* xfc)
Packit Service fa4841
{
Packit Service fa4841
	if (xfc->xevents)
Packit Service fa4841
	{
Packit Service fa4841
		ArrayList_Free(xfc->xevents);
Packit Service fa4841
		xfc->xevents = NULL;
Packit Service fa4841
	}
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_execute_action_script(xfContext* xfc, const XEvent* event)
Packit Service fa4841
{
Packit Service fa4841
	int index;
Packit Service fa4841
	int count;
Packit Service fa4841
	char* name;
Packit Service fa4841
	FILE* actionScript;
Packit Service fa4841
	BOOL match = FALSE;
Packit Service fa4841
	const char* xeventName;
Packit Service fa4841
	char buffer[1024] = { 0 };
Packit Service fa4841
	char command[1024] = { 0 };
Packit Service fa4841
Packit Service b1ea74
	if (!xfc->actionScriptExists || !xfc->xevents || !xfc->window)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (event->type > LASTEvent)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	xeventName = x11_event_string(event->type);
Packit Service fa4841
	count = ArrayList_Count(xfc->xevents);
Packit Service fa4841
Packit Service fa4841
	for (index = 0; index < count; index++)
Packit Service fa4841
	{
Packit Service b1ea74
		name = (char*)ArrayList_GetItem(xfc->xevents, index);
Packit Service fa4841
Packit Service fa4841
		if (_stricmp(name, xeventName) == 0)
Packit Service fa4841
		{
Packit Service fa4841
			match = TRUE;
Packit Service fa4841
			break;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (!match)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service b1ea74
	sprintf_s(command, sizeof(command), "%s xevent %s %lu", xfc->context.settings->ActionScript,
Packit Service b1ea74
	          xeventName, (unsigned long)xfc->window->handle);
Packit Service fa4841
	actionScript = popen(command, "r");
Packit Service fa4841
Packit Service fa4841
	if (!actionScript)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	while (fgets(buffer, sizeof(buffer), actionScript))
Packit Service fa4841
	{
Packit Service b1ea74
		char* context = NULL;
Packit Service b1ea74
		strtok_s(buffer, "\n", &context);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	pclose(actionScript);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service fa4841
void xf_event_adjust_coordinates(xfContext* xfc, int* x, int* y)
Packit Service fa4841
{
Packit Service fa4841
	rdpSettings* settings;
Packit Service fa4841
Packit Service fa4841
	if (!xfc || !xfc->context.settings || !y || !x)
Packit Service fa4841
		return;
Packit Service fa4841
Packit Service fa4841
	settings = xfc->context.settings;
Packit Service fa4841
Packit Service fa4841
	if (!xfc->remote_app)
Packit Service fa4841
	{
Packit Service fa4841
#ifdef WITH_XRENDER
Packit Service fa4841
Packit Service fa4841
		if (xf_picture_transform_required(xfc))
Packit Service fa4841
		{
Packit Service fa4841
			double xScalingFactor = settings->DesktopWidth / (double)xfc->scaledWidth;
Packit Service fa4841
			double yScalingFactor = settings->DesktopHeight / (double)xfc->scaledHeight;
Packit Service fa4841
			*x = (int)((*x - xfc->offset_x) * xScalingFactor);
Packit Service fa4841
			*y = (int)((*y - xfc->offset_y) * yScalingFactor);
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
#endif
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	CLAMP_COORDINATES(*x, *y);
Packit Service fa4841
}
Packit Service b1ea74
static BOOL xf_event_Expose(xfContext* xfc, const XExposeEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	int x, y;
Packit Service fa4841
	int w, h;
Packit Service fa4841
	rdpSettings* settings = xfc->context.settings;
Packit Service fa4841
Packit Service fa4841
	if (!app && (settings->SmartSizing || settings->MultiTouchGestures))
Packit Service fa4841
	{
Packit Service fa4841
		x = 0;
Packit Service fa4841
		y = 0;
Packit Service fa4841
		w = settings->DesktopWidth;
Packit Service fa4841
		h = settings->DesktopHeight;
Packit Service fa4841
	}
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service b1ea74
		x = event->x;
Packit Service b1ea74
		y = event->y;
Packit Service b1ea74
		w = event->width;
Packit Service b1ea74
		h = event->height;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (!app)
Packit Service fa4841
	{
Packit Service b1ea74
		if (xfc->context.gdi->gfx)
Packit Service b1ea74
		{
Packit Service b1ea74
			xf_OutputExpose(xfc, x, y, w, h);
Packit Service b1ea74
			return TRUE;
Packit Service b1ea74
		}
Packit Service fa4841
		xf_draw_screen(xfc, x, y, w, h);
Packit Service fa4841
	}
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service fa4841
		xfAppWindow* appWindow;
Packit Service b1ea74
		appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
		if (appWindow)
Packit Service fa4841
		{
Packit Service fa4841
			xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_VisibilityNotify(xfContext* xfc, const XVisibilityEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	WINPR_UNUSED(app);
Packit Service b1ea74
	xfc->unobscured = event->state == VisibilityUnobscured;
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	rdpInput* input;
Packit Service fa4841
	Window childWindow;
Packit Service fa4841
	input = xfc->context.input;
Packit Service fa4841
Packit Service fa4841
	if (!xfc->context.settings->MouseMotion)
Packit Service fa4841
	{
Packit Service fa4841
		if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
Packit Service fa4841
			return TRUE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (app)
Packit Service fa4841
	{
Packit Service fa4841
		/* make sure window exists */
Packit Service fa4841
		if (!xf_AppWindowFromX11Window(xfc, window))
Packit Service fa4841
			return TRUE;
Packit Service fa4841
Packit Service fa4841
		/* Translate to desktop coordinates */
Packit Service b1ea74
		XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y, &x, &y,
Packit Service b1ea74
		                      &childWindow);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xf_event_adjust_coordinates(xfc, &x, &y);
Packit Service fa4841
	freerdp_input_send_mouse_event(input, PTR_FLAGS_MOVE, x, y);
Packit Service fa4841
Packit Service fa4841
	if (xfc->fullscreen && !app)
Packit Service fa4841
	{
Packit Service b1ea74
		XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
static BOOL xf_event_MotionNotify(xfContext* xfc, const XMotionEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	if (xfc->window)
Packit Service b1ea74
		xf_floatbar_set_root_y(xfc->window->floatbar, event->y);
Packit Service b1ea74
Packit Service fa4841
	if (xfc->use_xinput)
Packit Service fa4841
		return TRUE;
Packit Service fa4841
Packit Service b1ea74
	return xf_generic_MotionNotify(xfc, event->x, event->y, event->state, event->window, app);
Packit Service bb5c11
}
Packit Service b1ea74
Packit Service b1ea74
BOOL xf_generic_ButtonEvent(xfContext* xfc, int x, int y, int button, Window window, BOOL app,
Packit Service b1ea74
                            BOOL down)
Packit Service fa4841
{
Packit Service b1ea74
	UINT16 flags = 0;
Packit Service fa4841
	rdpInput* input;
Packit Service fa4841
	Window childWindow;
Packit Service b1ea74
	size_t i;
Packit Service fa4841
Packit Service b1ea74
	for (i = 0; i < ARRAYSIZE(xfc->button_map); i++)
Packit Service fa4841
	{
Packit Service b1ea74
		const button_map* cur = &xfc->button_map[i];
Packit Service bb5c11
Packit Service b1ea74
		if (cur->button == button)
Packit Service b1ea74
		{
Packit Service b1ea74
			flags = cur->flags;
Packit Service bb5c11
			break;
Packit Service b1ea74
		}
Packit Service bb5c11
	}
Packit Service fa4841
Packit Service b1ea74
	input = xfc->context.input;
Packit Service b1ea74
Packit Service fa4841
	if (flags != 0)
Packit Service fa4841
	{
Packit Service b1ea74
		if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
Packit Service fa4841
		{
Packit Service b1ea74
			if (down)
Packit Service b1ea74
				freerdp_input_send_mouse_event(input, flags, 0, 0);
Packit Service fa4841
		}
Packit Service fa4841
		else
Packit Service fa4841
		{
Packit Service b1ea74
			BOOL extended = FALSE;
Packit Service b1ea74
Packit Service b1ea74
			if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
Packit Service b1ea74
			{
Packit Service b1ea74
				extended = TRUE;
Packit Service b1ea74
Packit Service b1ea74
				if (down)
Packit Service b1ea74
					flags |= PTR_XFLAGS_DOWN;
Packit Service b1ea74
			}
Packit Service b1ea74
			else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
Packit Service b1ea74
			{
Packit Service b1ea74
				if (down)
Packit Service b1ea74
					flags |= PTR_FLAGS_DOWN;
Packit Service b1ea74
			}
Packit Service b1ea74
Packit Service fa4841
			if (app)
Packit Service fa4841
			{
Packit Service fa4841
				/* make sure window exists */
Packit Service fa4841
				if (!xf_AppWindowFromX11Window(xfc, window))
Packit Service fa4841
					return TRUE;
Packit Service fa4841
Packit Service fa4841
				/* Translate to desktop coordinates */
Packit Service b1ea74
				XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y,
Packit Service b1ea74
				                      &x, &y, &childWindow);
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			xf_event_adjust_coordinates(xfc, &x, &y);
Packit Service fa4841
Packit Service fa4841
			if (extended)
Packit Service fa4841
				freerdp_input_send_extended_mouse_event(input, flags, x, y);
Packit Service fa4841
			else
Packit Service fa4841
				freerdp_input_send_mouse_event(input, flags, x, y);
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
static BOOL xf_event_ButtonPress(xfContext* xfc, const XButtonEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	if (xfc->use_xinput)
Packit Service fa4841
		return TRUE;
Packit Service fa4841
Packit Service b1ea74
	return xf_generic_ButtonEvent(xfc, event->x, event->y, event->button, event->window, app, TRUE);
Packit Service fa4841
}
Packit Service fa4841
Packit Service b1ea74
static BOOL xf_event_ButtonRelease(xfContext* xfc, const XButtonEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	if (xfc->use_xinput)
Packit Service fa4841
		return TRUE;
Packit Service fa4841
Packit Service b1ea74
	return xf_generic_ButtonEvent(xfc, event->x, event->y, event->button, event->window, app,
Packit Service b1ea74
	                              FALSE);
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_KeyPress(xfContext* xfc, const XKeyEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	KeySym keysym;
Packit Service fa4841
	char str[256];
Packit Service b1ea74
	WINPR_UNUSED(app);
Packit Service b1ea74
	XLookupString((XKeyEvent*)event, str, sizeof(str), &keysym, NULL);
Packit Service b1ea74
	xf_keyboard_key_press(xfc, event->keycode, keysym);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_KeyRelease(xfContext* xfc, const XKeyEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	KeySym keysym;
Packit Service fa4841
	char str[256];
Packit Service b1ea74
	WINPR_UNUSED(app);
Packit Service b1ea74
	XLookupString((XKeyEvent*)event, str, sizeof(str), &keysym, NULL);
Packit Service b1ea74
	xf_keyboard_key_release(xfc, event->keycode, keysym);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_FocusIn(xfContext* xfc, const XFocusInEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	if (event->mode == NotifyGrab)
Packit Service fa4841
		return TRUE;
Packit Service fa4841
Packit Service fa4841
	xfc->focused = TRUE;
Packit Service fa4841
Packit Service fa4841
	if (xfc->mouse_active && !app)
Packit Service b1ea74
	{
Packit Service b1ea74
		if (!xfc->window)
Packit Service b1ea74
			return FALSE;
Packit Service b1ea74
Packit Service b1ea74
		XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync,
Packit Service b1ea74
		              CurrentTime);
Packit Service b1ea74
	}
Packit Service fa4841
Packit Service fa4841
	if (app)
Packit Service fa4841
	{
Packit Service fa4841
		xfAppWindow* appWindow;
Packit Service b1ea74
		xf_rail_send_activate(xfc, event->window, TRUE);
Packit Service b1ea74
		appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service b1ea74
		/* Update the server with any window changes that occurred while the window was not focused.
Packit Service b1ea74
		 */
Packit Service fa4841
		if (appWindow)
Packit Service fa4841
		{
Packit Service fa4841
			xf_rail_adjust_position(xfc, appWindow);
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xf_keyboard_focus_in(xfc);
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_FocusOut(xfContext* xfc, const XFocusOutEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	if (event->mode == NotifyUngrab)
Packit Service fa4841
		return TRUE;
Packit Service fa4841
Packit Service fa4841
	xfc->focused = FALSE;
Packit Service fa4841
Packit Service b1ea74
	if (event->mode == NotifyWhileGrabbed)
Packit Service fa4841
		XUngrabKeyboard(xfc->display, CurrentTime);
Packit Service fa4841
Packit Service fa4841
	xf_keyboard_release_all_keypress(xfc);
Packit Service fa4841
	xf_keyboard_clear(xfc);
Packit Service fa4841
Packit Service fa4841
	if (app)
Packit Service b1ea74
		xf_rail_send_activate(xfc, event->window, FALSE);
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_MappingNotify(xfContext* xfc, const XMappingEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	WINPR_UNUSED(app);
Packit Service b1ea74
Packit Service b1ea74
	if (event->request == MappingModifier)
Packit Service fa4841
	{
Packit Service fa4841
		if (xfc->modifierMap)
Packit Service fa4841
			XFreeModifiermap(xfc->modifierMap);
Packit Service fa4841
Packit Service fa4841
		xfc->modifierMap = XGetModifierMapping(xfc->display);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_ClientMessage(xfContext* xfc, const XClientMessageEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	if ((event->message_type == xfc->WM_PROTOCOLS) &&
Packit Service b1ea74
	    ((Atom)event->data.l[0] == xfc->WM_DELETE_WINDOW))
Packit Service fa4841
	{
Packit Service fa4841
		if (app)
Packit Service fa4841
		{
Packit Service fa4841
			xfAppWindow* appWindow;
Packit Service b1ea74
			appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
			if (appWindow)
Packit Service fa4841
			{
Packit Service fa4841
				xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			return TRUE;
Packit Service fa4841
		}
Packit Service fa4841
		else
Packit Service fa4841
		{
Packit Service fa4841
			DEBUG_X11("Main window closed");
Packit Service fa4841
			return FALSE;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_EnterNotify(xfContext* xfc, const XEnterWindowEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	if (!app)
Packit Service fa4841
	{
Packit Service b1ea74
		if (!xfc->window)
Packit Service b1ea74
			return FALSE;
Packit Service b1ea74
Packit Service fa4841
		xfc->mouse_active = TRUE;
Packit Service fa4841
Packit Service fa4841
		if (xfc->fullscreen)
Packit Service b1ea74
			XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
Packit Service fa4841
Packit Service fa4841
		if (xfc->focused)
Packit Service b1ea74
			XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync,
Packit Service b1ea74
			              CurrentTime);
Packit Service fa4841
	}
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service fa4841
		xfAppWindow* appWindow;
Packit Service b1ea74
		appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
		/* keep track of which window has focus so that we can apply pointer updates */
Packit Service fa4841
Packit Service fa4841
		if (appWindow)
Packit Service fa4841
		{
Packit Service fa4841
			xfc->appWindow = appWindow;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_LeaveNotify(xfContext* xfc, const XLeaveWindowEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service b1ea74
	WINPR_UNUSED(event);
Packit Service b1ea74
Packit Service fa4841
	if (!app)
Packit Service fa4841
	{
Packit Service fa4841
		xfc->mouse_active = FALSE;
Packit Service fa4841
		XUngrabKeyboard(xfc->display, CurrentTime);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_ConfigureNotify(xfContext* xfc, const XConfigureEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	Window childWindow;
Packit Service fa4841
	xfAppWindow* appWindow;
Packit Service b1ea74
	rdpSettings* settings;
Packit Service b1ea74
	settings = xfc->context.settings;
Packit Service fa4841
Packit Service fa4841
	if (!app)
Packit Service fa4841
	{
Packit Service b1ea74
		if (!xfc->window)
Packit Service b1ea74
			return FALSE;
Packit Service b1ea74
Packit Service b1ea74
		if (xfc->window->left != event->x)
Packit Service b1ea74
			xfc->window->left = event->x;
Packit Service fa4841
Packit Service b1ea74
		if (xfc->window->top != event->y)
Packit Service b1ea74
			xfc->window->top = event->y;
Packit Service fa4841
Packit Service b1ea74
		if (xfc->window->width != event->width || xfc->window->height != event->height)
Packit Service fa4841
		{
Packit Service b1ea74
			xfc->window->width = event->width;
Packit Service b1ea74
			xfc->window->height = event->height;
Packit Service fa4841
#ifdef WITH_XRENDER
Packit Service fa4841
			xfc->offset_x = 0;
Packit Service fa4841
			xfc->offset_y = 0;
Packit Service fa4841
Packit Service b1ea74
			if (xfc->context.settings->SmartSizing || xfc->context.settings->MultiTouchGestures)
Packit Service fa4841
			{
Packit Service fa4841
				xfc->scaledWidth = xfc->window->width;
Packit Service fa4841
				xfc->scaledHeight = xfc->window->height;
Packit Service fa4841
				xf_draw_screen(xfc, 0, 0, settings->DesktopWidth, settings->DesktopHeight);
Packit Service fa4841
			}
Packit Service fa4841
			else
Packit Service fa4841
			{
Packit Service fa4841
				xfc->scaledWidth = settings->DesktopWidth;
Packit Service fa4841
				xfc->scaledHeight = settings->DesktopHeight;
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
#endif
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (settings->DynamicResolutionUpdate)
Packit Service fa4841
		{
Packit Service fa4841
			int alignedWidth, alignedHeight;
Packit Service fa4841
			alignedWidth = (xfc->window->width / 2) * 2;
Packit Service fa4841
			alignedHeight = (xfc->window->height / 2) * 2;
Packit Service fa4841
			/* ask the server to resize using the display channel */
Packit Service fa4841
			xf_disp_handle_configureNotify(xfc, alignedWidth, alignedHeight);
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		return TRUE;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service b1ea74
	appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
	if (appWindow)
Packit Service fa4841
	{
Packit Service fa4841
		/*
Packit Service fa4841
		 * ConfigureNotify coordinates are expressed relative to the window parent.
Packit Service fa4841
		 * Translate these to root window coordinates.
Packit Service fa4841
		 */
Packit Service b1ea74
		XTranslateCoordinates(xfc->display, appWindow->handle, RootWindowOfScreen(xfc->screen), 0,
Packit Service b1ea74
		                      0, &appWindow->x, &appWindow->y, &childWindow);
Packit Service b1ea74
		appWindow->width = event->width;
Packit Service b1ea74
		appWindow->height = event->height;
Packit Service fa4841
Packit Service fa4841
		/*
Packit Service fa4841
		 * Additional checks for not in a local move and not ignoring configure to send
Packit Service fa4841
		 * position update to server, also should the window not be focused then do not
Packit Service fa4841
		 * send to server yet (i.e. resizing using window decoration).
Packit Service fa4841
		 * The server will be updated when the window gets refocused.
Packit Service fa4841
		 */
Packit Service fa4841
		if (appWindow->decorations)
Packit Service fa4841
		{
Packit Service fa4841
			/* moving resizing using window decoration */
Packit Service fa4841
			xf_rail_adjust_position(xfc, appWindow);
Packit Service fa4841
		}
Packit Service fa4841
		else
Packit Service fa4841
		{
Packit Service b1ea74
			if ((!event->send_event || appWindow->local_move.state == LMS_NOT_ACTIVE) &&
Packit Service b1ea74
			    !appWindow->rail_ignore_configure && xfc->focused)
Packit Service fa4841
				xf_rail_adjust_position(xfc, appWindow);
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_MapNotify(xfContext* xfc, const XMapEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	xfAppWindow* appWindow;
Packit Service fa4841
Packit Service fa4841
	if (!app)
Packit Service fa4841
		gdi_send_suppress_output(xfc->context.gdi, FALSE);
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service b1ea74
		appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
		if (appWindow)
Packit Service fa4841
		{
Packit Service fa4841
			/* local restore event */
Packit Service fa4841
			/* This is now handled as part of the PropertyNotify
Packit Service fa4841
			 * Doing this here would inhibit the ability to restore a maximized window
Packit Service fa4841
			 * that is minimized back to the maximized state
Packit Service fa4841
			 */
Packit Service b1ea74
			xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
Packit Service fa4841
			appWindow->is_mapped = TRUE;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_UnmapNotify(xfContext* xfc, const XUnmapEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	xfAppWindow* appWindow;
Packit Service fa4841
	xf_keyboard_release_all_keypress(xfc);
Packit Service fa4841
Packit Service fa4841
	if (!app)
Packit Service fa4841
		gdi_send_suppress_output(xfc->context.gdi, TRUE);
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service b1ea74
		appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
		if (appWindow)
Packit Service fa4841
		{
Packit Service fa4841
			appWindow->is_mapped = FALSE;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event, BOOL app)
Packit Service fa4841
{
Packit Service fa4841
	/*
Packit Service fa4841
	 * This section handles sending the appropriate commands to the rail server
Packit Service fa4841
	 * when the window has been minimized, maximized, restored locally
Packit Service fa4841
	 * ie. not using the buttons on the rail window itself
Packit Service fa4841
	 */
Packit Service b1ea74
	if ((((Atom)event->atom == xfc->_NET_WM_STATE) && (event->state != PropertyDelete)) ||
Packit Service b1ea74
	    (((Atom)event->atom == xfc->WM_STATE) && (event->state != PropertyDelete)))
Packit Service fa4841
	{
Packit Service b1ea74
		unsigned long i;
Packit Service fa4841
		BOOL status;
Packit Service fa4841
		BOOL maxVert = FALSE;
Packit Service fa4841
		BOOL maxHorz = FALSE;
Packit Service fa4841
		BOOL minimized = FALSE;
Packit Service fa4841
		BOOL minimizedChanged = FALSE;
Packit Service fa4841
		unsigned long nitems;
Packit Service fa4841
		unsigned long bytes;
Packit Service fa4841
		unsigned char* prop;
Packit Service fa4841
		xfAppWindow* appWindow = NULL;
Packit Service fa4841
Packit Service fa4841
		if (app)
Packit Service fa4841
		{
Packit Service b1ea74
			appWindow = xf_AppWindowFromX11Window(xfc, event->window);
Packit Service fa4841
Packit Service fa4841
			if (!appWindow)
Packit Service fa4841
				return TRUE;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service b1ea74
		if ((Atom)event->atom == xfc->_NET_WM_STATE)
Packit Service fa4841
		{
Packit Service b1ea74
			status = xf_GetWindowProperty(xfc, event->window, xfc->_NET_WM_STATE, 12, &nitems,
Packit Service b1ea74
			                              &bytes, &prop);
Packit Service fa4841
Packit Service fa4841
			if (status)
Packit Service fa4841
			{
Packit Service fa4841
				for (i = 0; i < nitems; i++)
Packit Service fa4841
				{
Packit Service b1ea74
					if ((Atom)((UINT16**)prop)[i] ==
Packit Service b1ea74
					    XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False))
Packit Service fa4841
					{
Packit Service fa4841
						maxVert = TRUE;
Packit Service fa4841
					}
Packit Service fa4841
Packit Service b1ea74
					if ((Atom)((UINT16**)prop)[i] ==
Packit Service b1ea74
					    XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False))
Packit Service fa4841
					{
Packit Service fa4841
						maxHorz = TRUE;
Packit Service fa4841
					}
Packit Service fa4841
				}
Packit Service fa4841
Packit Service fa4841
				XFree(prop);
Packit Service fa4841
			}
Packit Service fa4841
		}
Packit Service fa4841
Packit Service b1ea74
		if ((Atom)event->atom == xfc->WM_STATE)
Packit Service fa4841
		{
Packit Service b1ea74
			status =
Packit Service b1ea74
			    xf_GetWindowProperty(xfc, event->window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
Packit Service fa4841
Packit Service fa4841
			if (status)
Packit Service fa4841
			{
Packit Service fa4841
				/* If the window is in the iconic state */
Packit Service b1ea74
				if (((UINT32)*prop == 3))
Packit Service fa4841
					minimized = TRUE;
Packit Service fa4841
				else
Packit Service fa4841
					minimized = FALSE;
Packit Service fa4841
Packit Service fa4841
				minimizedChanged = TRUE;
Packit Service fa4841
				XFree(prop);
Packit Service fa4841
			}
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		if (app)
Packit Service fa4841
		{
Packit Service b1ea74
			if (maxVert && maxHorz && !minimized &&
Packit Service b1ea74
			    (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED))
Packit Service fa4841
			{
Packit Service fa4841
				appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
Packit Service fa4841
				xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE);
Packit Service fa4841
			}
Packit Service fa4841
			else if (minimized && (appWindow->rail_state != WINDOW_SHOW_MINIMIZED))
Packit Service fa4841
			{
Packit Service fa4841
				appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
Packit Service fa4841
				xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE);
Packit Service fa4841
			}
Packit Service b1ea74
			else if (!minimized && !maxVert && !maxHorz && (appWindow->rail_state != WINDOW_SHOW) &&
Packit Service b1ea74
			         (appWindow->rail_state != WINDOW_HIDE))
Packit Service fa4841
			{
Packit Service fa4841
				appWindow->rail_state = WINDOW_SHOW;
Packit Service fa4841
				xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
Packit Service fa4841
			}
Packit Service fa4841
		}
Packit Service fa4841
		else if (minimizedChanged)
Packit Service fa4841
			gdi_send_suppress_output(xfc->context.gdi, minimized);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, const XEvent* event)
Packit Service fa4841
{
Packit Service fa4841
	if (!xfc->remote_app)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	switch (appWindow->local_move.state)
Packit Service fa4841
	{
Packit Service fa4841
		case LMS_NOT_ACTIVE:
Packit Service fa4841
Packit Service fa4841
			/* No local move in progress, nothing to do */
Packit Service fa4841
Packit Service b1ea74
			/* Prevent Configure from happening during indeterminant state of Horz or Vert Max only
Packit Service b1ea74
			 */
Packit Service fa4841
			if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure)
Packit Service fa4841
			{
Packit Service fa4841
				appWindow->rail_ignore_configure = FALSE;
Packit Service fa4841
				return TRUE;
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case LMS_STARTING:
Packit Service fa4841
Packit Service b1ea74
			/* Local move initiated by RDP server, but we have not yet seen any updates from the X
Packit Service b1ea74
			 * server */
Packit Service fa4841
			switch (event->type)
Packit Service fa4841
			{
Packit Service fa4841
				case ConfigureNotify:
Packit Service b1ea74
					/* Starting to see move events from the X server. Local move is now in progress.
Packit Service b1ea74
					 */
Packit Service fa4841
					appWindow->local_move.state = LMS_ACTIVE;
Packit Service b1ea74
					/* Allow these events to be processed during move to keep our state up to date.
Packit Service b1ea74
					 */
Packit Service fa4841
					break;
Packit Service fa4841
Packit Service fa4841
				case ButtonPress:
Packit Service fa4841
				case ButtonRelease:
Packit Service fa4841
				case KeyPress:
Packit Service fa4841
				case KeyRelease:
Packit Service fa4841
				case UnmapNotify:
Packit Service fa4841
					/*
Packit Service fa4841
					 * A button release event means the X window server did not grab the
Packit Service fa4841
					 * mouse before the user released it. In this case we must cancel the
Packit Service fa4841
					 * local move. The event will be processed below as normal, below.
Packit Service fa4841
					 */
Packit Service fa4841
					break;
Packit Service fa4841
Packit Service fa4841
				case VisibilityNotify:
Packit Service fa4841
				case PropertyNotify:
Packit Service fa4841
				case Expose:
Packit Service fa4841
					/* Allow these events to pass */
Packit Service fa4841
					break;
Packit Service fa4841
Packit Service fa4841
				default:
Packit Service fa4841
					/* Eat any other events */
Packit Service fa4841
					return TRUE;
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case LMS_ACTIVE:
Packit Service fa4841
Packit Service fa4841
			/* Local move is in progress */
Packit Service fa4841
			switch (event->type)
Packit Service fa4841
			{
Packit Service fa4841
				case ConfigureNotify:
Packit Service fa4841
				case VisibilityNotify:
Packit Service fa4841
				case PropertyNotify:
Packit Service fa4841
				case Expose:
Packit Service fa4841
				case GravityNotify:
Packit Service fa4841
					/* Keep us up to date on position */
Packit Service fa4841
					break;
Packit Service fa4841
Packit Service fa4841
				default:
Packit Service fa4841
					/* Any other event terminates move */
Packit Service fa4841
					xf_rail_end_local_move(xfc, appWindow);
Packit Service fa4841
					break;
Packit Service fa4841
			}
Packit Service fa4841
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case LMS_TERMINATING:
Packit Service fa4841
			/* Already sent RDP end move to server. Allow events to pass. */
Packit Service fa4841
			break;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return FALSE;
Packit Service fa4841
}
Packit Service b1ea74
Packit Service b1ea74
BOOL xf_event_process(freerdp* instance, const XEvent* event)
Packit Service fa4841
{
Packit Service fa4841
	BOOL status = TRUE;
Packit Service fa4841
	xfAppWindow* appWindow;
Packit Service b1ea74
	xfContext* xfc = (xfContext*)instance->context;
Packit Service fa4841
	rdpSettings* settings = xfc->context.settings;
Packit Service fa4841
Packit Service fa4841
	if (xfc->remote_app)
Packit Service fa4841
	{
Packit Service fa4841
		appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
Packit Service fa4841
Packit Service fa4841
		if (appWindow)
Packit Service fa4841
		{
Packit Service fa4841
			/* Update "current" window for cursor change orders */
Packit Service fa4841
			xfc->appWindow = appWindow;
Packit Service fa4841
Packit Service fa4841
			if (xf_event_suppress_events(xfc, appWindow, event))
Packit Service fa4841
				return TRUE;
Packit Service fa4841
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service b1ea74
	if (xfc->window)
Packit Service fa4841
	{
Packit Service b1ea74
		if (xf_floatbar_check_event(xfc->window->floatbar, event))
Packit Service b1ea74
		{
Packit Service b1ea74
			xf_floatbar_event_process(xfc->window->floatbar, event);
Packit Service b1ea74
			return TRUE;
Packit Service b1ea74
		}
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xf_event_execute_action_script(xfc, event);
Packit Service fa4841
Packit Service fa4841
	if (event->type != MotionNotify)
Packit Service fa4841
	{
Packit Service b1ea74
		DEBUG_X11("%s Event(%d): wnd=0x%08lX", x11_event_string(event->type), event->type,
Packit Service b1ea74
		          (unsigned long)event->xany.window);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	switch (event->type)
Packit Service fa4841
	{
Packit Service fa4841
		case Expose:
Packit Service b1ea74
			status = xf_event_Expose(xfc, &event->xexpose, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case VisibilityNotify:
Packit Service b1ea74
			status = xf_event_VisibilityNotify(xfc, &event->xvisibility, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case MotionNotify:
Packit Service b1ea74
			status = xf_event_MotionNotify(xfc, &event->xmotion, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case ButtonPress:
Packit Service b1ea74
			status = xf_event_ButtonPress(xfc, &event->xbutton, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case ButtonRelease:
Packit Service b1ea74
			status = xf_event_ButtonRelease(xfc, &event->xbutton, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case KeyPress:
Packit Service b1ea74
			status = xf_event_KeyPress(xfc, &event->xkey, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case KeyRelease:
Packit Service b1ea74
			status = xf_event_KeyRelease(xfc, &event->xkey, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case FocusIn:
Packit Service b1ea74
			status = xf_event_FocusIn(xfc, &event->xfocus, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case FocusOut:
Packit Service b1ea74
			status = xf_event_FocusOut(xfc, &event->xfocus, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case EnterNotify:
Packit Service b1ea74
			status = xf_event_EnterNotify(xfc, &event->xcrossing, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case LeaveNotify:
Packit Service b1ea74
			status = xf_event_LeaveNotify(xfc, &event->xcrossing, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case NoExpose:
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case GraphicsExpose:
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case ConfigureNotify:
Packit Service b1ea74
			status = xf_event_ConfigureNotify(xfc, &event->xconfigure, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case MapNotify:
Packit Service b1ea74
			status = xf_event_MapNotify(xfc, &event->xmap, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case UnmapNotify:
Packit Service b1ea74
			status = xf_event_UnmapNotify(xfc, &event->xunmap, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case ReparentNotify:
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case MappingNotify:
Packit Service b1ea74
			status = xf_event_MappingNotify(xfc, &event->xmapping, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case ClientMessage:
Packit Service b1ea74
			status = xf_event_ClientMessage(xfc, &event->xclient, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		case PropertyNotify:
Packit Service b1ea74
			status = xf_event_PropertyNotify(xfc, &event->xproperty, xfc->remote_app);
Packit Service fa4841
			break;
Packit Service fa4841
Packit Service fa4841
		default:
Packit Service fa4841
			if (settings->SupportDisplayControl)
Packit Service fa4841
				xf_disp_handle_xevent(xfc, event);
Packit Service fa4841
Packit Service fa4841
			break;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	xf_cliprdr_handle_xevent(xfc, event);
Packit Service fa4841
	xf_input_handle_event(xfc, event);
Packit Service fa4841
	XSync(xfc->display, FALSE);
Packit Service fa4841
	return status;
Packit Service fa4841
}