/****************************************************************************
**
** Implementation of TQCursor class for X11
**
** Created : 940219
**
** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
**
** This file is part of the kernel module of the TQt GUI Toolkit.
**
** This file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the files LICENSE.GPL2
** and LICENSE.GPL3 included in the packaging of this file.
** Alternatively you may (at your option) use any later version
** of the GNU General Public License if such license has been
** publicly approved by Trolltech ASA (or its successors, if any)
** and the KDE Free TQt Foundation.
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/.
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** This file may be used under the terms of the Q Public License as
** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
** included in the packaging of this file.  Licensees holding valid TQt
** Commercial licenses may use this file in accordance with the TQt
** Commercial License Agreement provided with the Software.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
** herein.
**
**********************************************************************/

#include "tqcursor.h"
#include "tqbitmap.h"
#include "tqimage.h"
#include "tqapplication.h"
#include "tqdatastream.h"
#include "tqnamespace.h"
#include "tqt_x11_p.h"
#include <X11/cursorfont.h>

#ifndef TQT_NO_XCURSOR
#  include <X11/Xcursor/Xcursor.h>
#endif // TQT_NO_XCURSOR

#ifdef USE_QT4

/*****************************************************************************
  Global cursors
 *****************************************************************************/

static TQCursor cursorTable[TQt::LastCursor+1];

static const int arrowCursorIdx = 0;

TQT_STATIC_CONST_IMPL TQCursor & TQt::arrowCursor = cursorTable[0];
TQT_STATIC_CONST_IMPL TQCursor & TQt::upArrowCursor = cursorTable[1];
TQT_STATIC_CONST_IMPL TQCursor & TQt::crossCursor = cursorTable[2];
TQT_STATIC_CONST_IMPL TQCursor & TQt::waitCursor = cursorTable[3];
TQT_STATIC_CONST_IMPL TQCursor & TQt::ibeamCursor = cursorTable[4];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeVerCursor = cursorTable[5];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeHorCursor = cursorTable[6];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeBDiagCursor = cursorTable[7];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeFDiagCursor = cursorTable[8];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeAllCursor = cursorTable[9];
TQT_STATIC_CONST_IMPL TQCursor & TQt::blankCursor = cursorTable[10];
TQT_STATIC_CONST_IMPL TQCursor & TQt::splitVCursor = cursorTable[11];
TQT_STATIC_CONST_IMPL TQCursor & TQt::splitHCursor = cursorTable[12];
TQT_STATIC_CONST_IMPL TQCursor & TQt::pointingHandCursor = cursorTable[13];
TQT_STATIC_CONST_IMPL TQCursor & TQt::forbiddenCursor = cursorTable[14];
TQT_STATIC_CONST_IMPL TQCursor & TQt::whatsThisCursor = cursorTable[15];
TQT_STATIC_CONST_IMPL TQCursor & TQt::busyCursor = cursorTable[16];

//     TQT_STATIC_CONST TQCursor & arrowCursor = Qt::ArrowCursor;
//     TQT_STATIC_CONST TQCursor & upArrowCursor = Qt::UpArrowCursor;
//     TQT_STATIC_CONST TQCursor & crossCursor = Qt::CrossCursor;
//     TQT_STATIC_CONST TQCursor & waitCursor = Qt::WaitCursor;
//     TQT_STATIC_CONST TQCursor & ibeamCursor = Qt::IBeamCursor;
//     TQT_STATIC_CONST TQCursor & sizeVerCursor = Qt::SizeVerCursor;
//     TQT_STATIC_CONST TQCursor & sizeHorCursor = Qt::SizeHorCursor;
//     TQT_STATIC_CONST TQCursor & sizeBDiagCursor = Qt::SizeBDiagCursor;
//     TQT_STATIC_CONST TQCursor & sizeFDiagCursor = Qt::SizeFDiagCursor;
//     TQT_STATIC_CONST TQCursor & sizeAllCursor = Qt::SizeAllCursor;
//     TQT_STATIC_CONST TQCursor & blankCursor = Qt::BlankCursor;
//     TQT_STATIC_CONST TQCursor & splitVCursor = Qt::SplitVCursor;
//     TQT_STATIC_CONST TQCursor & splitHCursor = Qt::SplitHCursor;
//     TQT_STATIC_CONST TQCursor & pointingHandCursor = Qt::PointingHandCursor;
//     TQT_STATIC_CONST TQCursor & forbiddenCursor = Qt::ForbiddenCursor;
//     TQT_STATIC_CONST TQCursor & whatsThisCursor = Qt::WhatsThisCursor;
//     TQT_STATIC_CONST TQCursor & busyCursor = Qt::BusyCursor;

// TQT_STATIC_CONST_IMPL TQCursor & TQt::arrowCursor = Qt::ArrowCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::upArrowCursor = Qt::UpArrowCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::crossCursor = Qt::CrossCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::waitCursor = Qt::WaitCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::ibeamCursor = Qt::IBeamCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeVerCursor = Qt::SizeVerCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeHorCursor = Qt::SizeHorCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeBDiagCursor = Qt::SizeBDiagCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeFDiagCursor = Qt::SizeFDiagCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeAllCursor = Qt::SizeAllCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::blankCursor = Qt::BlankCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::splitVCursor = Qt::SplitVCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::splitHCursor = Qt::SplitHCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::pointingHandCursor = Qt::PointingHandCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::forbiddenCursor = Qt::ForbiddenCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::whatsThisCursor = Qt::WhatsThisCursor;
// TQT_STATIC_CONST_IMPL TQCursor & TQt::busyCursor = Qt::BusyCursor;

/*****************************************************************************
  Internal TQCursorData class
 *****************************************************************************/

// struct TQCursorData : public TQShared
// {
//     TQCursorData( int s = 0 );
//    ~TQCursorData();
//     int	      ctqshape;
//     TQBitmap  *bm, *bmm;
//     short     hx, hy;
//     XColor    fg,bg;
//     Cursor    hcurs;
//     Pixmap    pm, pmm;
// };
// 
// TQCursorData::TQCursorData( int s )
// {
//     ctqshape = s;
//     hcurs = 0;
//     bm = bmm = 0;
//     hx = hy  = 0;
//     pm = pmm = 0;
// }

// TQCursorData::~TQCursorData()
// {
//     Display *dpy = TQPaintDevice::x11AppDisplay();
// 
//     // Add in checking for the display too as on HP-UX
//     // we seem to get a core dump as the cursor data is
//     // deleted again from main() on exit...
//     if ( hcurs && dpy )
// 	XFreeCursor( dpy, hcurs );
//     if ( pm && dpy )
// 	XFreePixmap( dpy, pm );
//     if ( pmm && dpy )
// 	XFreePixmap( dpy, pmm );
//     delete bm;
//     delete bmm;
// }

static bool initialized = FALSE;

/*!
    Internal function that deinitializes the predefined cursors.
    This function is called from the TQApplication destructor.

    \sa initialize()
*/
void TQCursor::cleanup()
{
    if ( !initialized )
	return;

//     int tqshape;
//     for( tqshape = 0; tqshape <= LastCursor; tqshape++ ) {
// 	if ( cursorTable[tqshape].data && cursorTable[tqshape].data->deref() )
// 	    delete cursorTable[tqshape].data;
// 	cursorTable[tqshape].data = 0;
//     }

    initialized = FALSE;
}


/*!
    Internal function that initializes the predefined cursors.
    This function is called from the TQApplication constructor.

    \sa cleanup()
*/

void TQCursor::initialize()
{
//     int tqshape;
//     for( tqshape = 0; tqshape <= LastCursor; tqshape++ )
// 	cursorTable[tqshape].data = new TQCursorData( tqshape );
//     initialized = TRUE;
//     qAddPostRoutine( cleanup );

    int tqshape;
    for( tqshape = 0; tqshape <= TQt::LastCursor; tqshape++ ) {
        switch(tqshape) {
	   case  0: new(&cursorTable[tqshape]) TQCursor(Qt::ArrowCursor);		break;
	   case  1: new(&cursorTable[tqshape]) TQCursor(Qt::UpArrowCursor);		break;
	   case  2: new(&cursorTable[tqshape]) TQCursor(Qt::CrossCursor);		break;
	   case  3: new(&cursorTable[tqshape]) TQCursor(Qt::WaitCursor);		break;
	   case  4: new(&cursorTable[tqshape]) TQCursor(Qt::IBeamCursor);		break;
	   case  5: new(&cursorTable[tqshape]) TQCursor(Qt::SizeVerCursor);		break;
	   case  6: new(&cursorTable[tqshape]) TQCursor(Qt::SizeHorCursor);		break;
	   case  7: new(&cursorTable[tqshape]) TQCursor(Qt::SizeBDiagCursor);		break;
	   case  8: new(&cursorTable[tqshape]) TQCursor(Qt::SizeFDiagCursor);		break;
	   case  9: new(&cursorTable[tqshape]) TQCursor(Qt::SizeAllCursor);		break;
	   case 10: new(&cursorTable[tqshape]) TQCursor(Qt::BlankCursor);		break;
	   case 11: new(&cursorTable[tqshape]) TQCursor(Qt::SplitVCursor);		break;
	   case 12: new(&cursorTable[tqshape]) TQCursor(Qt::SplitHCursor);		break;
	   case 13: new(&cursorTable[tqshape]) TQCursor(Qt::PointingHandCursor);	break;
	   case 14: new(&cursorTable[tqshape]) TQCursor(Qt::ForbiddenCursor);		break;
	   case 15: new(&cursorTable[tqshape]) TQCursor(Qt::WhatsThisCursor);		break;
	   case 16: new(&cursorTable[tqshape]) TQCursor(Qt::BusyCursor);		break;
	   case 17: new(&cursorTable[tqshape]) TQCursor(Qt::OpenHandCursor);		break;
	   case 18: new(&cursorTable[tqshape]) TQCursor(Qt::ClosedHandCursor);		break;
	   case 19: new(&cursorTable[tqshape]) TQCursor(Qt::DragCopyCursor);		break;
	   case 20: new(&cursorTable[tqshape]) TQCursor(Qt::DragMoveCursor);		break;
	   case 21: new(&cursorTable[tqshape]) TQCursor(Qt::DragLinkCursor);		break;
        }
    }
    initialized = TRUE;
    qAddPostRoutine( cleanup );
}

#else // USE_QT4

// Define TQT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
// use the ugly X11 cursors.

/*****************************************************************************
  Internal TQCursorData class
 *****************************************************************************/

struct TQCursorData : public TQShared
{
    TQCursorData( int s = 0 );
   ~TQCursorData();
    int	      ctqshape;
    TQBitmap  *bm, *bmm;
    short     hx, hy;
    XColor    fg,bg;
    Cursor    hcurs;
    Pixmap    pm, pmm;
};

TQCursorData::TQCursorData( int s )
{
    ctqshape = s;
    hcurs = 0;
    bm = bmm = 0;
    hx = hy  = 0;
    pm = pmm = 0;
}

TQCursorData::~TQCursorData()
{
    Display *dpy = TQPaintDevice::x11AppDisplay();

    // Add in checking for the display too as on HP-UX
    // we seem to get a core dump as the cursor data is
    // deleted again from main() on exit...
    if ( hcurs && dpy )
	XFreeCursor( dpy, hcurs );
    if ( pm && dpy )
	XFreePixmap( dpy, pm );
    if ( pmm && dpy )
	XFreePixmap( dpy, pmm );
    delete bm;
    delete bmm;
}


/*****************************************************************************
  Global cursors
 *****************************************************************************/

static TQCursor cursorTable[TQt::LastCursor+1];

static const int arrowCursorIdx = 0;

TQT_STATIC_CONST_IMPL TQCursor & TQt::arrowCursor = cursorTable[0];
TQT_STATIC_CONST_IMPL TQCursor & TQt::upArrowCursor = cursorTable[1];
TQT_STATIC_CONST_IMPL TQCursor & TQt::crossCursor = cursorTable[2];
TQT_STATIC_CONST_IMPL TQCursor & TQt::waitCursor = cursorTable[3];
TQT_STATIC_CONST_IMPL TQCursor & TQt::ibeamCursor = cursorTable[4];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeVerCursor = cursorTable[5];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeHorCursor = cursorTable[6];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeBDiagCursor = cursorTable[7];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeFDiagCursor = cursorTable[8];
TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeAllCursor = cursorTable[9];
TQT_STATIC_CONST_IMPL TQCursor & TQt::blankCursor = cursorTable[10];
TQT_STATIC_CONST_IMPL TQCursor & TQt::splitVCursor = cursorTable[11];
TQT_STATIC_CONST_IMPL TQCursor & TQt::splitHCursor = cursorTable[12];
TQT_STATIC_CONST_IMPL TQCursor & TQt::pointingHandCursor = cursorTable[13];
TQT_STATIC_CONST_IMPL TQCursor & TQt::forbiddenCursor = cursorTable[14];
TQT_STATIC_CONST_IMPL TQCursor & TQt::whatsThisCursor = cursorTable[15];
TQT_STATIC_CONST_IMPL TQCursor & TQt::busyCursor = cursorTable[16];


TQCursor *TQCursor::find_cur( int tqshape )		// find predefined cursor
{
    return (uint)tqshape <= LastCursor ? &cursorTable[tqshape] : 0;
}


static bool initialized = FALSE;

/*!
    Internal function that deinitializes the predefined cursors.
    This function is called from the TQApplication destructor.

    \sa initialize()
*/
void TQCursor::cleanup()
{
    if ( !initialized )
	return;

    int tqshape;
    for( tqshape = 0; tqshape <= LastCursor; tqshape++ ) {
	if ( cursorTable[tqshape].data && cursorTable[tqshape].data->deref() )
	    delete cursorTable[tqshape].data;
	cursorTable[tqshape].data = 0;
    }
    initialized = FALSE;
}


/*!
    Internal function that initializes the predefined cursors.
    This function is called from the TQApplication constructor.

    \sa cleanup()
*/

void TQCursor::initialize()
{
    int tqshape;
    for( tqshape = 0; tqshape <= LastCursor; tqshape++ )
	cursorTable[tqshape].data = new TQCursorData( tqshape );
    initialized = TRUE;
    qAddPostRoutine( cleanup );
}


/*!
    Constructs a cursor with the default arrow tqshape.
*/
TQCursor::TQCursor()
{
    if ( !initialized ) {
	if ( tqApp->startingUp() ) {
	    data = 0;
	    return;
	}
	initialize();
    }
    TQCursor* c = &cursorTable[arrowCursorIdx];
    c->data->ref();
    data = c->data;
}



/*!
    Constructs a cursor with the specified \a tqshape.

    See \l tqCursorShape for a list of tqshapes.

    \sa setShape()
*/

TQCursor::TQCursor( int tqshape )
{
    if ( !initialized )
	initialize();
    TQCursor *c = find_cur( tqshape );
    if ( !c )					// not found
	c = &cursorTable[arrowCursorIdx];	//   then use arrowCursor
    c->data->ref();
    data = c->data;
}

/*!
    Constructs a cursor from the window system cursor \a cursor.

    \warning Using this function is not portable. This function is only
    available on X11 and Windows.
*/
TQCursor::TQCursor( HANDLE cursor )
{
    if ( !initialized )
	initialize();

    data = new TQCursorData;
    TQ_CHECK_PTR( data );
    data->hcurs = cursor;
}



void TQCursor::setBitmap( const TQBitmap &bitmap, const TQBitmap &mask,
			 int hotX, int hotY )
{
    if ( !initialized )
	initialize();
    if ( bitmap.depth() != 1 || mask.depth() != 1 ||
	 bitmap.size() != mask.size() ) {
#if defined(TQT_CHECK_NULL)
	qWarning( "TQCursor: Cannot create bitmap cursor; invalid bitmap(s)" );
#endif
	TQCursor *c = &cursorTable[arrowCursorIdx];
	c->data->ref();
	data = c->data;
	return;
    }
    data = new TQCursorData;
    TQ_CHECK_PTR( data );
    data->bm  = new TQBitmap( bitmap );
    data->bmm = new TQBitmap( mask );
    data->hcurs = 0;
    data->ctqshape = BitmapCursor;
    data->hx = hotX >= 0 ? hotX : bitmap.width()/2;
    data->hy = hotY >= 0 ? hotY : bitmap.height()/2;
    data->fg.red   = 0 << 8;
    data->fg.green = 0 << 8;
    data->fg.blue  = 0 << 8;
    data->bg.red   = 255 << 8;
    data->bg.green = 255 << 8;
    data->bg.blue  = 255 << 8;
    update(); // Xcursor's backward compatibility hack needs the cursor to be created
              // right after the bitmaps are created and filled with data
}


/*!
    Constructs a copy of the cursor \a c.
*/

TQCursor::TQCursor( const TQCursor &c )
{
    if ( !initialized )
	initialize();
    data = c.data;				// shallow copy
    data->ref();
}

/*!
    Destroys the cursor.
*/

TQCursor::~TQCursor()
{
    if ( data && data->deref() )
	delete data;
}


/*!
    Assigns \a c to this cursor and returns a reference to this
    cursor.
*/

TQCursor &TQCursor::operator=( const TQCursor &c )
{
    if ( !initialized )
	initialize();
    c.data->ref();				// avoid c = c
    if ( data->deref() )
	delete data;
    data = c.data;
    return *this;
}


/*!
    Returns the cursor tqshape identifier. The return value is one of
    the \l tqCursorShape enum values (cast to an int).

    \sa setShape()
*/

int TQCursor::tqshape() const
{
    if ( !initialized )
	initialize();
    return data->ctqshape;
}

/*!
    Sets the cursor to the tqshape identified by \a tqshape.

    See \l tqCursorShape for the list of cursor tqshapes.

    \sa tqshape()
*/

void TQCursor::setShape( int tqshape )
{
    if ( !initialized )
	initialize();
    TQCursor *c = find_cur( tqshape );		// find one of the global ones
    if ( !c )					// not found
	c = &cursorTable[arrowCursorIdx];	//   then use arrowCursor
    c->data->ref();
    if ( data->deref() )			// make shallow copy
	delete data;
    data = c->data;
}


/*!
    Returns the cursor bitmap, or 0 if it is one of the standard
    cursors.
*/
const TQBitmap *TQCursor::bitmap() const
{
    if ( !initialized )
	initialize();
    return data->bm;
}

/*!
    Returns the cursor bitmap mask, or 0 if it is one of the standard
    cursors.
*/

const TQBitmap *TQCursor::mask() const
{
    if ( !initialized )
	initialize();
    return data->bmm;
}

/*!
    Returns the cursor hot spot, or (0, 0) if it is one of the
    standard cursors.
*/

TQPoint TQCursor::hotSpot() const
{
    if ( !initialized )
	initialize();
    return TQPoint( data->hx, data->hy );
}


/*!
    Returns the window system cursor handle.

    \warning
    Portable in principle, but if you use it you are probably about to
    do something non-portable. Be careful.
*/

TQt::HANDLE TQCursor::handle() const
{
    if ( !initialized )
	initialize();
    if ( !data->hcurs )
	update();
    return data->hcurs;
}

/*!
    \fn TQCursor::TQCursor( HCURSOR handle )

    Creates a cursor with the specified window system handle \a
    handle.

    \warning
    Portable in principle, but if you use it you are probably about to
    do something non-portable. Be careful.
*/

/*!
    Returns the position of the cursor (hot spot) in global screen
    coordinates.

    You can call TQWidget::mapFromGlobal() to translate it to widget
    coordinates.

    \sa setPos(), TQWidget::mapFromGlobal(), TQWidget::mapToGlobal()
*/
TQPoint TQCursor::pos()
{
    Window root;
    Window child;
    int root_x, root_y, win_x, win_y;
    uint buttons;
    Display* dpy = TQPaintDevice::x11AppDisplay();
    for ( int i = 0; i < ScreenCount( dpy ); i++ ) {
	if ( XQueryPointer( dpy, TQPaintDevice::x11AppRootWindow( i ), &root, &child,
			    &root_x, &root_y, &win_x, &win_y, &buttons ) )

	    return TQPoint( root_x, root_y );
    }
    return TQPoint();
}

/*! \internal
*/
int TQCursor::x11Screen()
{
    Window root;
    Window child;
    int root_x, root_y, win_x, win_y;
    uint buttons;
    Display* dpy = TQPaintDevice::x11AppDisplay();
    for ( int i = 0; i < ScreenCount( dpy ); i++ ) {
	if ( XQueryPointer( dpy, TQPaintDevice::x11AppRootWindow( i ), &root, &child,
			    &root_x, &root_y, &win_x, &win_y, &buttons ) )
	    return i;
    }
    return -1;
}

/*!
    Moves the cursor (hot spot) to the global screen position (\a x,
    \a y).

    You can call TQWidget::mapToGlobal() to translate widget
    coordinates to global screen coordinates.

    \sa pos(), TQWidget::mapFromGlobal(), TQWidget::mapToGlobal()
*/

void TQCursor::setPos( int x, int y )
{
    TQPoint current, target(x, y);

    // this is copied from pos(), since we need the screen number for the correct
    // root window in the XWarpPointer call
    Window root;
    Window child;
    int root_x, root_y, win_x, win_y;
    uint buttons;
    Display* dpy = TQPaintDevice::x11AppDisplay();
    int screen;
    for ( screen = 0; screen < ScreenCount( dpy ); screen++ ) {
	if ( XQueryPointer( dpy, TQPaintDevice::x11AppRootWindow( screen ), &root, &child,
			    &root_x, &root_y, &win_x, &win_y, &buttons ) ) {
	    current = TQPoint( root_x, root_y );
	    break;
	}
    }

    if ( screen >= ScreenCount( dpy ) )
	return;

    // Need to check, since some X servers generate null mouse move
    // events, causing looping in applications which call setPos() on
    // every mouse move event.
    //
    if ( current == target )
	return;

    XWarpPointer( TQPaintDevice::x11AppDisplay(), None,
		  TQPaintDevice::x11AppRootWindow( screen ),
		  0, 0, 0, 0, x, y );
}

/*!
    \overload void TQCursor::setPos ( const TQPoint & )
*/


/*!
    \internal

    Creates the cursor.
*/

void TQCursor::update() const
{
    if ( !initialized )
	initialize();
    register TQCursorData *d = data;		// cheat const!
    if ( d->hcurs )				// already loaded
	return;

    Display *dpy = TQPaintDevice::x11AppDisplay();
    Window rootwin = TQPaintDevice::x11AppRootWindow();

    if ( d->ctqshape == BitmapCursor ) {
	d->hcurs = XCreatePixmapCursor( dpy, d->bm->handle(), d->bmm->handle(),
					&d->fg, &d->bg, d->hx, d->hy );
	return;
    }

#ifndef TQT_NO_XCURSOR
    static const char *cursorNames[] = {
	"left_ptr",
	"up_arrow",
	"cross",
	"wait",
	"ibeam",
	"size_ver",
	"size_hor",
	"size_bdiag",
	"size_fdiag",
	"size_all",
	"blank",
	"split_v",
	"split_h",
	"pointing_hand",
	"forbidden",
	"whats_this",
	"left_ptr_watch"
    };

    d->hcurs = XcursorLibraryLoadCursor( dpy, cursorNames[d->ctqshape] );
    if ( d->hcurs )
	return;
#endif // TQT_NO_XCURSOR

    static uchar cur_blank_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    // Non-standard X11 cursors are created from bitmaps

#ifndef TQT_USE_APPROXIMATE_CURSORS
    static const uchar cur_ver_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
	0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
    static const uchar mcur_ver_bits[] = {
	0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
	0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
	0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
    static const uchar cur_hor_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
	0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    static const uchar mcur_hor_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
	0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
	0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
    static const uchar cur_bdiag_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
	0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
	0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    static const uchar mcur_bdiag_bits[] = {
	0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
	0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
	0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
    static const uchar cur_fdiag_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
	0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
	0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
    static const uchar mcur_fdiag_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
	0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
	0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
    static const uchar *cursor_bits16[] = {
	cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
	cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
	0, 0, cur_blank_bits, cur_blank_bits };

    static const uchar vsplit_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
	0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    static const uchar vsplitm_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
	0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
	0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
	0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
	0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
	0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
	0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
	0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    static const uchar hsplit_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
	0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
	0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
	0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
	0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
	0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    static const uchar hsplitm_bits[] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
	0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
	0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
	0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
	0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
	0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    static const uchar whatsthis_bits[] = {
        0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
        0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
        0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
        0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
        0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
        0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
        0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
    static const uchar whatsthism_bits[] = {
        0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
        0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
        0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
        0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
        0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
        0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
        0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
    static const uchar busy_bits[] = {
	0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
	0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
	0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
	0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
	0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
	0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
	0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
	0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    static const uchar busym_bits[] = {
	0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
	0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
	0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
	0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
	0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
	0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
	0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
	0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    static const uchar * const cursor_bits32[] = {
	vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
	0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
    };

    static const uchar forbidden_bits[] = {
	0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
	0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
	0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
	0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };

    static const unsigned char forbiddenm_bits[] = {
	0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
	0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
	0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
	0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};

    static const uchar * const cursor_bits20[] = {
	forbidden_bits, forbiddenm_bits
    };

    if ( d->ctqshape >= SizeVerCursor && d->ctqshape < SizeAllCursor ||
	 d->ctqshape == BlankCursor ) {
	XColor bg, fg;
	bg.red   = 255 << 8;
	bg.green = 255 << 8;
	bg.blue  = 255 << 8;
	fg.red   = 0;
	fg.green = 0;
	fg.blue  = 0;
	int i = (d->ctqshape - SizeVerCursor)*2;
	d->pm  = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits16[i],
					16, 16 );
	d->pmm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits16[i+1],
					16,16);
	d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg, &bg, 8, 8 );
	return;
    }
    if ( ( d->ctqshape >= SplitVCursor && d->ctqshape <= SplitHCursor ) ||
         d->ctqshape == WhatsThisCursor || d->ctqshape == BusyCursor ) {
	XColor bg, fg;
	bg.red   = 255 << 8;
	bg.green = 255 << 8;
	bg.blue  = 255 << 8;
	fg.red   = 0;
	fg.green = 0;
	fg.blue  = 0;
	int i = (d->ctqshape - SplitVCursor)*2;
	d->pm  = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits32[i],
					32, 32 );
	d->pmm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits32[i+1],
					32, 32);
	int hs = ( d->ctqshape == PointingHandCursor ||
		   d->ctqshape == WhatsThisCursor ||
		   d->ctqshape == BusyCursor ) ? 0 : 16;
	d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg, &bg, hs, hs );
	return;
    }
    if ( d->ctqshape == ForbiddenCursor ) {
	XColor bg, fg;
	bg.red   = 255 << 8;
	bg.green = 255 << 8;
	bg.blue  = 255 << 8;
	fg.red   = 0;
	fg.green = 0;
	fg.blue  = 0;
	int i = (d->ctqshape - ForbiddenCursor)*2;
	d->pm  = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits20[i],
					20, 20 );
	d->pmm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits20[i+1],
					20, 20);
	d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg, &bg, 10, 10 );
	return;
    }
#endif /* ! TQT_USE_APPROXIMATE_CURSORS */

    uint sh;
    switch ( d->ctqshape ) {			// map Q cursor to X cursor
    case ArrowCursor:
	sh = XC_left_ptr;
	break;
    case UpArrowCursor:
	sh = XC_center_ptr;
	break;
    case CrossCursor:
	sh = XC_crosshair;
	break;
    case WaitCursor:
	sh = XC_watch;
	break;
    case IbeamCursor:
	sh = XC_xterm;
	break;
    case SizeAllCursor:
	sh = XC_fleur;
	break;
    case PointingHandCursor:
	sh = XC_hand2;
	break;
#ifdef TQT_USE_APPROXIMATE_CURSORS
    case SizeBDiagCursor:
	sh = XC_top_right_corner;
	break;
    case SizeFDiagCursor:
	sh = XC_bottom_right_corner;
	break;
    case BlankCursor:
	XColor bg, fg;
	bg.red   = 255 << 8;
	bg.green = 255 << 8;
	bg.blue  = 255 << 8;
	fg.red   = 0;
	fg.green = 0;
	fg.blue  = 0;
	d->pm  = XCreateBitmapFromData( dpy, rootwin,
					(char *)cur_blank_bits, 16, 16 );
	d->pmm = XCreateBitmapFromData( dpy, rootwin,
					(char *)cur_blank_bits, 16,16);
	d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg,
					&bg, 8, 8 );
	return;
	break;
    case SizeVerCursor:
    case SplitVCursor:
	sh = XC_sb_v_double_arrow;
	break;
    case SizeHorCursor:
    case SplitHCursor:
	sh = XC_sb_h_double_arrow;
	break;
    case WhatsThisCursor:
	sh = XC_question_arrow;
	break;
    case ForbiddenCursor:
	sh = XC_circle;
	break;
    case BusyCursor:
	sh = XC_watch;
	break;
#endif /* TQT_USE_APPROXIMATE_CURSORS */
    default:
#if defined(TQT_CHECK_RANGE)
	qWarning( "TQCursor::update: Invalid cursor tqshape %d", d->ctqshape );
#endif
	return;
    }
    d->hcurs = XCreateFontCursor( dpy, sh );
}

#endif // USE_QT4