Blame libxklavier/xklavier_evt_xkb.c

Packit Service 93d855
/*
Packit Service 93d855
 * Copyright (C) 2002-2006 Sergey V. Udaltsov <svu@gnome.org>
Packit Service 93d855
 *
Packit Service 93d855
 * This library is free software; you can redistribute it and/or
Packit Service 93d855
 * modify it under the terms of the GNU Lesser General Public
Packit Service 93d855
 * License as published by the Free Software Foundation; either
Packit Service 93d855
 * version 2 of the License, or (at your option) any later version.
Packit Service 93d855
 *
Packit Service 93d855
 * This library is distributed in the hope that it will be useful,
Packit Service 93d855
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 93d855
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 93d855
 * Lesser General Public License for more details.
Packit Service 93d855
 *
Packit Service 93d855
 * You should have received a copy of the GNU Lesser General Public
Packit Service 93d855
 * License along with this library; if not, write to the
Packit Service 93d855
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service 93d855
 * Boston, MA 02111-1307, USA.
Packit Service 93d855
 */
Packit Service 93d855
Packit Service 93d855
#include <time.h>
Packit Service 93d855
Packit Service 93d855
#include <X11/Xatom.h>
Packit Service 93d855
#include <X11/Xlib.h>
Packit Service 93d855
#include <X11/Xutil.h>
Packit Service 93d855
Packit Service 93d855
#include "xklavier_private.h"
Packit Service 93d855
#include "xklavier_private_xkb.h"
Packit Service 93d855
Packit Service 93d855
#ifdef HAVE_XINPUT
Packit Service 93d855
#include "config.h"
Packit Service 93d855
#include "X11/extensions/XInput.h"
Packit Service 93d855
Packit Service 93d855
static gint
Packit Service 93d855
xkl_xinput_process_x_event(XklEngine * engine, XEvent * xev)
Packit Service 93d855
{
Packit Service 93d855
	XDevicePresenceNotifyEvent *dpne =
Packit Service 93d855
	    (XDevicePresenceNotifyEvent *) xev;
Packit Service 93d855
	xkl_debug(200, "XInput event detected: %d\n", dpne->devchange);
Packit Service 93d855
	if (dpne->devchange == DeviceEnabled) {
Packit Service 93d855
		xkl_debug(150, "Device enabled: %d\n", dpne->deviceid);
Packit Service 93d855
		g_signal_emit_by_name(engine, "X-new-device");
Packit Service 93d855
	}
Packit Service 93d855
	return 1;
Packit Service 93d855
}
Packit Service 93d855
#endif
Packit Service 93d855
Packit Service 93d855
/*
Packit Service 93d855
 * XKB event handler
Packit Service 93d855
 */
Packit Service 93d855
gint
Packit Service 93d855
xkl_xkb_process_x_event(XklEngine * engine, XEvent * xev)
Packit Service 93d855
{
Packit Service 93d855
#ifdef LIBXKBFILE_PRESENT
Packit Service 93d855
	gint i;
Packit Service 93d855
	guint bit;
Packit Service 93d855
	guint inds;
Packit Service 93d855
	XkbEvent *kev = (XkbEvent *) xev;
Packit Service 93d855
Packit Service 93d855
	if (!
Packit Service 93d855
	    (xkl_engine_is_listening_for(engine, XKLL_MANAGE_WINDOW_STATES)
Packit Service 93d855
	     | xkl_engine_is_listening_for(engine,
Packit Service 93d855
					   XKLL_TRACK_KEYBOARD_STATE)))
Packit Service 93d855
		return 0;
Packit Service 93d855
Packit Service 93d855
#ifdef HAVE_XINPUT
Packit Service 93d855
	/* Special case XInput event */
Packit Service 93d855
	if (xev->type == xkl_engine_backend(engine, XklXkb, xi_event_type))
Packit Service 93d855
		return xkl_xinput_process_x_event(engine, xev);
Packit Service 93d855
#endif
Packit Service 93d855
Packit Service 93d855
	if (xev->type != xkl_engine_backend(engine, XklXkb, event_type))
Packit Service 93d855
		return 0;
Packit Service 93d855
Packit Service 93d855
	xkl_debug(150, "Xkb event detected\n");
Packit Service 93d855
Packit Service 93d855
	switch (kev->any.xkb_type) {
Packit Service 93d855
		/*
Packit Service 93d855
		 * Group is changed!
Packit Service 93d855
		 */
Packit Service 93d855
	case XkbStateNotify:
Packit Service 93d855
#define GROUP_CHANGE_MASK \
Packit Service 93d855
    ( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask )
Packit Service 93d855
Packit Service 93d855
		xkl_debug(150,
Packit Service 93d855
			  "XkbStateNotify detected, changes: %X/(mask %X), new group %d\n",
Packit Service 93d855
			  kev->state.changed, GROUP_CHANGE_MASK,
Packit Service 93d855
			  kev->state.locked_group);
Packit Service 93d855
Packit Service 93d855
		if (kev->state.changed & GROUP_CHANGE_MASK)
Packit Service 93d855
			xkl_engine_process_state_modification(engine,
Packit Service 93d855
							      GROUP_CHANGED,
Packit Service 93d855
							      kev->
Packit Service 93d855
							      state.locked_group,
Packit Service 93d855
							      0, FALSE);
Packit Service 93d855
		else {		/* ...not interested... */
Packit Service 93d855
Packit Service 93d855
			xkl_debug(200,
Packit Service 93d855
				  "This type of state notification is not regarding groups\n");
Packit Service 93d855
			if (kev->state.locked_group !=
Packit Service 93d855
			    xkl_engine_priv(engine, curr_state).group)
Packit Service 93d855
				xkl_debug(0,
Packit Service 93d855
					  "ATTENTION! Currently cached group %d is not equal to the current group from the event: %d\n!",
Packit Service 93d855
					  xkl_engine_priv(engine,
Packit Service 93d855
							  curr_state).group,
Packit Service 93d855
					  kev->state.locked_group);
Packit Service 93d855
		}
Packit Service 93d855
Packit Service 93d855
		break;
Packit Service 93d855
Packit Service 93d855
		/*
Packit Service 93d855
		 * Indicators are changed!
Packit Service 93d855
		 */
Packit Service 93d855
	case XkbIndicatorStateNotify:
Packit Service 93d855
Packit Service 93d855
		xkl_debug(150, "XkbIndicatorStateNotify\n");
Packit Service 93d855
Packit Service 93d855
		inds = xkl_engine_priv(engine, curr_state).indicators;
Packit Service 93d855
Packit Service 93d855
		ForPhysIndicators(i,
Packit Service 93d855
				  bit) if (kev->indicators.changed & bit) {
Packit Service 93d855
			if (kev->indicators.state & bit)
Packit Service 93d855
				inds |= bit;
Packit Service 93d855
			else
Packit Service 93d855
				inds &= ~bit;
Packit Service 93d855
		}
Packit Service 93d855
Packit Service 93d855
		xkl_engine_process_state_modification(engine,
Packit Service 93d855
						      INDICATORS_CHANGED,
Packit Service 93d855
						      0, inds, TRUE);
Packit Service 93d855
		break;
Packit Service 93d855
Packit Service 93d855
		/*
Packit Service 93d855
		 * The configuration is changed!
Packit Service 93d855
		 */
Packit Service 93d855
	case XkbIndicatorMapNotify:
Packit Service 93d855
	case XkbControlsNotify:
Packit Service 93d855
	case XkbNamesNotify:
Packit Service 93d855
#if 0
Packit Service 93d855
		/* not really fair - but still better than flooding... */
Packit Service 93d855
		XklDebug(200,
Packit Service 93d855
			 "warning: configuration event %s is not actually processed\n",
Packit Service 93d855
			 _XklXkbGetXkbEventName(kev->any.xkb_type));
Packit Service 93d855
		break;
Packit Service 93d855
#endif
Packit Service 93d855
	case XkbNewKeyboardNotify:
Packit Service 93d855
		xkl_debug(150, "%s\n",
Packit Service 93d855
			  xkl_xkb_event_get_name(kev->any.xkb_type));
Packit Service 93d855
		xkl_engine_reset_all_info(engine, FALSE,
Packit Service 93d855
					  "XKB event: XkbNewKeyboardNotify");
Packit Service 93d855
		break;
Packit Service 93d855
Packit Service 93d855
		/*
Packit Service 93d855
		 * ...Not interested...
Packit Service 93d855
		 */
Packit Service 93d855
	default:
Packit Service 93d855
		xkl_debug(150, "Unknown XKB event %d [%s]\n",
Packit Service 93d855
			  kev->any.xkb_type,
Packit Service 93d855
			  xkl_xkb_event_get_name(kev->any.xkb_type));
Packit Service 93d855
		return 0;
Packit Service 93d855
	}
Packit Service 93d855
	return 1;
Packit Service 93d855
#else
Packit Service 93d855
	return 0;
Packit Service 93d855
#endif
Packit Service 93d855
}
Packit Service 93d855
Packit Service 93d855
/*
Packit Service 93d855
 * XKB error handler
Packit Service 93d855
 */
Packit Service 93d855
gint
Packit Service 93d855
xkl_xkb_process_x_error(XklEngine * engine, XErrorEvent * xerev)
Packit Service 93d855
{
Packit Service 93d855
#ifdef HAVE_XINPUT
Packit Service 93d855
	/* Ignore XInput errors */
Packit Service 93d855
	if (xerev->error_code >=
Packit Service 93d855
	    xkl_engine_backend(engine, XklXkb, xi_error_code)
Packit Service 93d855
	    && xerev->error_code <=
Packit Service 93d855
	    (xkl_engine_backend(engine, XklXkb, xi_error_code) +
Packit Service 93d855
	     XI_BadClass))
Packit Service 93d855
Packit Service 93d855
		return 1;
Packit Service 93d855
#endif
Packit Service 93d855
Packit Service 93d855
	return 0;
Packit Service 93d855
}
Packit Service 93d855
Packit Service 93d855
void
Packit Service 93d855
xkl_xkb_set_indicators(XklEngine * engine, const XklState * window_state)
Packit Service 93d855
{
Packit Service 93d855
#ifdef LIBXKBFILE_PRESENT
Packit Service 93d855
	int i;
Packit Service 93d855
	unsigned bit;
Packit Service 93d855
Packit Service 93d855
	XkbDescPtr cached =
Packit Service 93d855
	    xkl_engine_backend(engine, XklXkb, cached_desc);
Packit Service 93d855
	ForPhysIndicators(i, bit) if (cached->names->indicators[i] != None) {
Packit Service 93d855
		gboolean status;
Packit Service 93d855
		status = xkl_xkb_set_indicator(engine, i,
Packit Service 93d855
					       (window_state->indicators &
Packit Service 93d855
						bit) != 0);
Packit Service 93d855
		xkl_debug(150, "Set indicator \"%s\"/%d to %d: %d\n",
Packit Service 93d855
			  xkl_engine_backend(engine, XklXkb,
Packit Service 93d855
					     indicator_names)[i],
Packit Service 93d855
			  cached->names->indicators[i],
Packit Service 93d855
			  window_state->indicators & bit, status);
Packit Service 93d855
	}
Packit Service 93d855
#endif
Packit Service 93d855
}