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 
#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; iempty() && 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( &ke, ev.val.key.c, ev.val.key.alt, 
                        ev.val.key.ctrl, ev.val.key.shift);
                sendEvent( &ke );
                es->pop_front();
                break;
            case EVMOUSE:
                XEvent me;
                buildButtonEvent( &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( &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,&wx,&i);
    set_trap();
    window = XmuClientWindow (gDisplay, wx);
    i = XFetchName( gDisplay, window, &_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;
}