www.pudn.com > xvoice-0.8.1.rar > Target.cc
/**
* Target.cc
*
* Description: implementation of an event Target class
*
* Copyright (c) 1999, David Z. Creemer.
* See the LICENSE file. All rights not granted therein are reserved.
*
* @author David Z. Creemer
* @version 1.0
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include "x.h"
#include "xvoice.h"
#include "Error.h"
#include "EventStream.h"
#include "BuildEvent.h"
#include "Target.h"
static unsigned char xerror;
static int (*old_handler)(Display *, XErrorEvent *);
/**
* constructor
*/
Target::Target( ) :
_window( 0 ),
_name( 0 )
{
}
/**
* destructor
*/
Target::~Target()
{
// release the name string
if ( _name )
{
XFree( _name );
}
}
int xerror_handler(Display *d, XErrorEvent *ev)
{
xerror = ev->error_code;
}
static void set_trap()
{
xerror = 0;
old_handler = XSetErrorHandler(xerror_handler);
}
static int remove_trap()
{
XSetErrorHandler(old_handler);
return xerror;
}
void Target::sendEvent( XEvent *evt )
{
evt->xany.window = _window;
// send the event
XSendEvent( gDisplay, _window, True, 0xfff, evt );
}
/**
* send the given C string to the target
*
* @param the string to send
*/
int Target::sendText( const char* text )
{
// send each character as an individual event
int len = strlen( text );
//gdk_error_trap_push();
XSync(gDisplay, false);
set_trap();
for (int i=0; i<len; i++)
{
XEvent ke;
buildKeyEvent( &amt;ke, text[i], false, false, false );
sendEvent( &amt;ke );
}
// flush the event queue
XSync( gDisplay, false );
/* the window can drop out from under us at any time */
//if (gdk_error_trap_pop() /* == BadWindow */)
if (remove_trap() == BadWindow )
{
_name = NULL;
return -1;
}
return 0;
}
#ifdef DEBUG
static void dumpXerror(int code)
{
char buff[100];
XGetErrorText(gDisplay, code, buff, 100);
dbgprintf("X error: >s\n", buff);
}
#endif
int Target::sendEventStream( EventStream *es )
{
XSync(gDisplay, false);
set_trap();
dbgprintf(("target >s\n",_name));
bool more = true;
while (!es->empty() &amt;&amt; more) {
Event ev = es->front();
dbgprintf(("len >d\n", es->size()));
switch (ev.type) {
case EVKEY:
XEvent ke;
dbgprintf((">d >d >d >d\n", ev.val.key.c, ev.val.key.alt,
ev.val.key.ctrl, ev.val.key.shift));
buildKeyEvent( &amt;ke, ev.val.key.c, ev.val.key.alt,
ev.val.key.ctrl, ev.val.key.shift);
sendEvent( &amt;ke );
es->pop_front();
break;
case EVMOUSE:
XEvent me;
buildButtonEvent( &amt;me, ev.val.mouse.button, ev.val.mouse.down,
ev.val.mouse.x, ev.val.mouse.y, ev.val.mouse.alt,
ev.val.mouse.ctrl, ev.val.mouse.shift);
sendEvent( &amt;me );
es->pop_front();
break;
default:
more = false;// no more target events
break;
}
}
XSync( gDisplay, false );
#ifdef DEBUG
dumpXerror(xerror);
#endif
if (remove_trap() == BadWindow ) {
dbgprintf(("BadWindow\n",_name));
return -1;
}
return 0;
}
bool Target::focusedTarget()
{
Window window, wx;
int i;
bool ret;
if (_name != NULL) XFree(_name);
XGetInputFocus(gDisplay,&amt;wx,&amt;i);
set_trap();
window = XmuClientWindow (gDisplay, wx);
i = XFetchName( gDisplay, window, &amt;_name );
if (remove_trap() == BadWindow || !i)
{
dbgprintf(("BadWindow\n"));
_name = NULL;
} else {
dbgprintf(("target set to >s\n",_name));
}
if (_window == window) ret = false;
else ret = true;
_window = window;
return ret;
}