LinuxQuestions.org
Latest LQ Deal: Linux Power User Bundle
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-16-2007, 09:43 PM   #1
GotWookiee
LQ Newbie
 
Registered: Jan 2007
Posts: 3

Rep: Reputation: 0
XLIB and/or KDE: Determing and Changing Window Focus


Since Guttorn helped me to solve my previous issue, I now have a new problem to solve:

I am modifying a pre-existing C program that redirects USB events from a Contour Designs ShuttlePro V2 to keystrokes.

Issue #1
Is possible to find out what window is currently focused in X and/or KDE? If I can determine this then I can make the functions of some of the buttons change depending on which window of my video editing application (Cinelerra CV) is focused, making those 15 buttons go a lot further.

Issue #2
Is it possible to force focus to a specific window. For example, I could a key that would make the timeline focused and another to make the viewer focused, or better yet make one button toggle between the two if my first issue works.

Thanks,
Matt

BTW, here is the program thus far if anyone is interested:
Code:
/* -*- indent-tabs-mode:T; c-basic-offset:8; tab-width:8; -*- vi: set ts=8 noet:
 * $Id: shuttlepro.c,v 1.1 2006/04/08 15:22:31 hudson Exp $
 *
 * Contour ShuttlePro v2 interface for Cinelerra.
 * Based heavily on code by Arendt David <admin@prnet.org>
 *
 * (c) 2006 Trammell Hudson <hudson@osresearch.net>
 *
 * Build with:
 *  gcc -O3 -W -Wall ./shuttlepro.c -o shuttlepro -L /usr/X11R6/lib -lX11 -lXtst
 */
#define DELAY 10

#define KEY 1
#define KEY1 256
#define KEY2 257
#define KEY3 258
#define KEY4 259
#define KEY5 260
#define KEY6 261
#define KEY7 262
#define KEY8 263
#define KEY9 264
#define KEY10 265
#define KEY11 266
#define KEY12 267
#define KEY13 268
#define KEY14 269
#define KEY15 270

#define JOGSHUTTLE 2
#define JOG 7
#define SHUTTLE 8
#define X_LAST_KEYSYM

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <linux/input.h>
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>


typedef struct input_event EV;
unsigned short		jogvalue = 0xffff;
int			shuttlevalue = 0xffff;
struct timeval		last_shuttle;
int			need_synthetic_shuttle;
Display *		display;


void initdisplay()
{
	int event, error, major, minor;
	display = XOpenDisplay(0);
	if (!display)
	{
		fprintf(stderr, "unable to open X display\n");
		exit(1);
	}
	if (!XTestQueryExtension(display, &event, &error, &major, &minor))
	{
		fprintf(stderr, "Xtest extensions not supported\n");
		XCloseDisplay(display);
		exit(1);
	}
}


void
sendkey(
	KeySym			modifier,
	KeySym			key
)
{
	KeyCode			modifiercode;
	KeyCode			keycode;

	if (modifier != 0)
	{
		modifiercode = XKeysymToKeycode(display, modifier);
		XTestFakeKeyEvent(display, modifiercode, True, DELAY);
	}

	keycode = XKeysymToKeycode(display, key);
	XTestFakeKeyEvent(display, keycode, True, DELAY);
	XTestFakeKeyEvent(display, keycode, False, DELAY);

	if (modifier != 0)
		XTestFakeKeyEvent(display, modifiercode, False, DELAY);

	XFlush(display);
}


/*
 * The keys on the Contour Shuttle Pro v2 are arranged like this:
 *
 *          1   2   3   4
 *        5   6   7   8   9
 *
 *        14    Jog     15
 *
 *           10     11
 *           12     13
 *
 */
static KeySym
button_mappings[][2] = {
//	[ 1]		= { XK_Delete },		// Extend Head
//	[ 2]		= { XK_Delete },		// Trim Head
//	[ 3]		= { XK_Delete },		// Extend Tail
//	[ 4]		= { XK_Delete },		// Trim Tail
//	[ 5]		= { 'v' },			// Nudge Back
//	[ 6]		= { 'b' },			// Nudge Forward
//	[ 7]		= { 'i' },			// Toggle Timeline/Viewer
	[ 8]		= { XK_Left, XK_Alt_L },		// Previous Edit/Media
	[ 9]		= { XK_Right, XK_Alt_L },		// Next Edit/Media
	[10]		= { '[', XK_Mode_switch },	// Mark In point
	[11]		= { 'v' },			// Splice
	[12]		= { ']', XK_Mode_switch },	// Mark Out point
	[13]		= { 'b' },			// Overwrite
	[14]		= { XK_KP_6 },			// Reverse
	[15]		= { XK_KP_3 },			// Play
};


void
key(
	unsigned short		code,
	unsigned int		value
)
{
	if( value == 0 )
	{
		// Button release (ignored)
		return;
	}

	code -= KEY1 - 1;

	// Bound check!
	if( code > 16 )
		return;

	KeySym * map = button_mappings[ code ];
	if( map[0] == 0 && map[1] == 0 )
		return; // Unmapped

	sendkey( map[1], map[0] );
/*
	{
	case KEY5 : sendkey(0, 'z'); break;			//undo
	case KEY14 : sendkey(XK_Mode_switch, '['); break;		//begin region
	case KEY15 : sendkey(XK_Mode_switch, ']'); break;		//end region
	case KEY8 : sendkey(0, 'v'); break;			//splice paste
	case KEY9 : sendkey(0, 'x'); break;			//cut
	}
*/
}


void
shuttle(
	int			value
)
{
	static int last_key = 100;

	gettimeofday( &last_shuttle, 0 );
	need_synthetic_shuttle = value != 0;

	if( value == shuttlevalue )
		return;
	shuttlevalue = value;

	switch( value )

	{
	case -7 : if (last_key != XK_KP_Add) sendkey(0, XK_KP_Add); last_key = XK_KP_Add; break;	// Reverse Fast
	case -6 : if (last_key != XK_KP_Add) sendkey(0, XK_KP_Add); last_key = XK_KP_Add; break;	// Reverse Fast
	case -5 : if (last_key != XK_KP_6) sendkey(0, XK_KP_6); last_key = XK_KP_6; break;		// Reverse Plaay
	case -4 : if (last_key != XK_KP_6) sendkey(0, XK_KP_6); last_key = XK_KP_6; break;		// Reverse Play
	case -3 : if (last_key != XK_KP_6) sendkey(0, XK_KP_6); last_key = XK_KP_6; break;		// Reverse Play
	case -2 : if (last_key != XK_KP_5) sendkey(0, XK_KP_5); last_key = XK_KP_5; break;		// Reverse Slow
	case -1 : if (last_key != XK_KP_5) sendkey(0, XK_KP_5); last_key = XK_KP_5; break;		// Reverse Slow
	case  0 : sendkey(0, XK_KP_0); break;								// Stop!
	case  1 : if (last_key != XK_KP_2) sendkey(0, XK_KP_2); last_key = XK_KP_2; break;		// Forward Slow
	case  2 : if (last_key != XK_KP_2) sendkey(0, XK_KP_2); last_key = XK_KP_2; break;		// Forward Slow
	case  3	: if (last_key != XK_KP_3) sendkey(0, XK_KP_3); last_key = XK_KP_3; break;		// Forward Play
	case  4	: if (last_key != XK_KP_3) sendkey(0, XK_KP_3); last_key = XK_KP_3; break;		// Forward Play
	case  5	: if (last_key != XK_KP_3) sendkey(0, XK_KP_3); last_key = XK_KP_3; break;		// Forward Play
	case  6 : if (last_key != XK_KP_Enter) sendkey(0, XK_KP_Enter); last_key = XK_KP_Enter; break;	// Forward Fast
	case  7 : if (last_key != XK_KP_Enter) sendkey(0, XK_KP_Enter); last_key = XK_KP_Enter; break;	// Forward Fast
	}
}


/*
 * Due to a bug (?) in the way Linux HID handles the ShuttlePro, the
 * center position is not reported for the shuttle wheel.  Instead,
 * a jog event is generated immediately when it returns.  We check to
 * see if the time since the last shuttle was more than a few ms ago
 * and generate a shuttle of 0 if so.
 */
void
check_synthetic()
{
	if( !need_synthetic_shuttle )
		return;

	struct timeval now, delta;
	gettimeofday( &now, 0 );
	timersub( &now, &last_shuttle, &delta );

	if( delta.tv_sec < 1 && delta.tv_usec < 5000 )
		return;
	
	shuttle( 0 );
	need_synthetic_shuttle = 0;
}


void
jog(
	unsigned int		value
)
{
	// We should generate a synthetic event for the shuttle going
	// to the home position if we have not seen one recently
	check_synthetic();

	if( jogvalue != 0xffff )
	{
		if (value < jogvalue)
			sendkey( 0, XK_KP_4 );
		else if (value > jogvalue)
			sendkey( 0, XK_KP_1 );
	}

	jogvalue = value;
}


void
jogshuttle(
	unsigned short		code,
	unsigned int		value
)
{
	switch (code)
	{
	case JOG	: jog(value); break;
	case SHUTTLE	: shuttle(value); break;
	}
}


void
handle_event(
	EV			ev
)
{
	switch (ev.type)
	{
	case KEY	: key(ev.code, ev.value); break;
	case JOGSHUTTLE : jogshuttle(ev.code, ev.value); break;
	}
}


int
main(
	int			argc,
	char **			argv
)
{
	char			name[256] = "unknown";
	EV			ev;

	if (argc < 2)
	{
		fprintf( stderr, "syntax: shuttlepro <device>\n" );
		return EXIT_FAILURE;
	}

	//printf("shuttlepro 0.1beta written by Arendt David (admin@prnet.org)v 1.1 \n");
	const char *		dev_name = argv[1];

	const int fd = open( dev_name, O_RDONLY );
	if (fd < 0)
	{
		fprintf( stderr, "unable to open %s\n", dev_name );
		return EXIT_FAILURE;
	}

	if( ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0 )
	{
		perror("evdev ioctl");
		return EXIT_FAILURE;
	}

	printf( "%s: %s\n", dev_name, name );

	/* Flag it as exclusive access */
	if( ioctl( fd, EVIOCGRAB, 1 ) < 0 )
	{
		perror( "evgrab ioctl" );
		return EXIT_FAILURE;
	}

	initdisplay();

	while (1)
	{
		read(fd, &ev, sizeof(ev));
		handle_event(ev);
	}

	close(fd);
	return 0;
}
 
Old 01-17-2007, 12:03 PM   #2
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 76
How about XGetInputFocus() and XSetInputFocus()?
 
Old 06-25-2009, 12:58 AM   #3
rishiv
LQ Newbie
 
Registered: Sep 2005
Location: Melbourne, Australia
Posts: 3

Rep: Reputation: 0
Question

GotWookie,

Thanks for posting your code, links and information! I'm trying to work with a ShuttlePro V2 under openSuSE 11.0 at the moment and am lost, never having had to deal with such complicated key bindings before...

Can you point me to any instructions on how to use your program, what it relies on and how to set up a build environment for it? Also, how is it used or invoked?

As you can probably guess, I've never undertaken anything with hardware inputs like this before, so am not sure where to start. I've done lots of reading based around using xbindkeys for extra buttons on devices, but from your posts it looks like this is the wrong approach.

Any help appreciated. Cheers,

Rishi.

My dmesg:
Code:
usb 1-1: new full speed USB device using ohci_hcd and address 2
usb 1-1: configuration #1 chosen from 1 choice
usb 1-1: New USB device found, idVendor=0b33, idProduct=0030
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-1: Product: ShuttlePRO v2
usb 1-1: Manufacturer: Contour Design
usbcore: registered new interface driver hiddev
input: Contour Design ShuttlePRO v2 as /class/input/input5
input,hidraw0: USB HID v1.10 Device [Contour Design ShuttlePRO v2] on usb-0000:00:06.0-1
usbcore: registered new interface driver usbhid
drivers/hid/usbhid/hid-core.c: v2.6:USB HID core driver
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Evolution, Firefox, KDE, and Window Focus Matir Linux - Software 4 03-02-2005 11:11 AM
KDE - Changing windows in one virtual window mikq Linux - Software 1 08-11-2004 02:47 PM
KDE 3.2 and changing window decorations brandor Linux - Software 6 06-21-2004 02:26 PM
Changing window managers in KDE or gnome under RH9 massey Linux - Newbie 4 01-21-2004 09:26 AM
How about changing window managers in KDE? jenna_h Linux - Software 8 11-09-2003 10:57 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration