|
|
|
/*
|
|
|
|
|
|
|
|
kxt.cpp - Xt enabled Qt classed (derived from Qt Extension QXt)
|
|
|
|
|
|
|
|
Copyright (c) 2000,2001 Stefan Schimanski <1Stein@gmx.de>
|
|
|
|
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
**
|
|
|
|
** Implementation of Qt extension classes for Xt/Motif support.
|
|
|
|
**
|
|
|
|
** Created : 980107
|
|
|
|
**
|
|
|
|
** Copyright (C) 1992-2000 Troll Tech AS. All rights reserved.
|
|
|
|
**
|
|
|
|
** This file is part of the Qt GUI Toolkit.
|
|
|
|
**
|
|
|
|
** This file may be distributed under the terms of the Q Public License
|
|
|
|
** as defined by Troll Tech AS of Norway and appearing in the file
|
|
|
|
** LICENSE.QPL included in the packaging of this file.
|
|
|
|
**
|
|
|
|
** Licensees holding valid Qt Professional Edition licenses may use this
|
|
|
|
** file in accordance with the Qt Professional Edition License Agreement
|
|
|
|
** provided with the Qt Professional Edition.
|
|
|
|
**
|
|
|
|
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
|
|
|
** information about the Professional Edition licensing, or see
|
|
|
|
** http://www.trolltech.com/qpl/ for QPL licensing information.
|
|
|
|
**
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include <tqglobal.h>
|
|
|
|
#if QT_VERSION < 0x030100
|
|
|
|
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <tqwidget.h>
|
|
|
|
#include <tqobjectlist.h>
|
|
|
|
#include <tqwidgetlist.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include "kxt.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Intrinsic.h>
|
|
|
|
#include <X11/IntrinsicP.h> // for XtCreateWindow
|
|
|
|
#include <X11/Shell.h>
|
|
|
|
#include <X11/StringDefs.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/Xos.h>
|
|
|
|
|
|
|
|
const int XKeyPress = KeyPress;
|
|
|
|
const int XKeyRelease = KeyRelease;
|
|
|
|
#undef KeyPress
|
|
|
|
#undef KeyRelease
|
|
|
|
|
|
|
|
extern Atom qt_wm_state;
|
|
|
|
|
|
|
|
//#define HAVE_MOTIF
|
|
|
|
#ifdef HAVE_MOTIF
|
|
|
|
#include <Xm/Xm.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef void (*SameAsXtTimerCallbackProc)(void*,void*);
|
|
|
|
typedef void (*IntervalSetter)(int);
|
|
|
|
typedef void (*ForeignEventProc)(XEvent*);
|
|
|
|
|
|
|
|
extern XtEventDispatchProc
|
|
|
|
qt_np_cascade_event_handler[LASTEvent]; // defined in qnpsupport.cpp
|
|
|
|
void qt_reset_color_avail(); // defined in qcolor_x11.cpp
|
|
|
|
int qt_activate_timers(); // defined in qapplication_x11.cpp
|
|
|
|
timeval *qt_wait_timer(); // defined in qapplication_x11.cpp
|
|
|
|
void qt_x11SendPostedEvents(); // defined in qapplication_x11.cpp
|
|
|
|
int qt_event_handler( XEvent* event ); // defined in qnpsupport.cpp
|
|
|
|
extern int qt_np_count; // defined in qnpsupport.cpp
|
|
|
|
void qt_np_timeout( void* p, void* id ); // defined in qnpsupport.cpp
|
|
|
|
void qt_np_add_timeoutcb(
|
|
|
|
SameAsXtTimerCallbackProc cb ); // defined in qnpsupport.cpp
|
|
|
|
void qt_np_remove_timeoutcb(
|
|
|
|
SameAsXtTimerCallbackProc cb ); // defined in qnpsupport.cpp
|
|
|
|
void qt_np_add_timer_setter(
|
|
|
|
IntervalSetter is ); // defined in qnpsupport.cpp
|
|
|
|
void qt_np_remove_timer_setter(
|
|
|
|
IntervalSetter is ); // defined in qnpsupport.cpp
|
|
|
|
extern XtIntervalId qt_np_timerid; // defined in qnpsupport.cpp
|
|
|
|
extern void (*qt_np_leave_cb)
|
|
|
|
(XLeaveWindowEvent*); // defined in qnpsupport.cpp
|
|
|
|
void qt_np_add_event_proc(
|
|
|
|
ForeignEventProc fep ); // defined in qnpsupport.cpp
|
|
|
|
void qt_np_remove_event_proc(
|
|
|
|
ForeignEventProc fep ); // defined in qnpsupport.cpp
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int empty;
|
|
|
|
} QWidgetClassPart;
|
|
|
|
|
|
|
|
typedef struct _QWidgetClassRec {
|
|
|
|
CoreClassPart core_class;
|
|
|
|
QWidgetClassPart qwidget_class;
|
|
|
|
} QWidgetClassRec;
|
|
|
|
|
|
|
|
//static QWidgetClassRec qwidgetClassRec;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
/* resources */
|
|
|
|
/* (none) */
|
|
|
|
/* private state */
|
|
|
|
KXtWidget* qxtwidget;
|
|
|
|
} QWidgetPart;
|
|
|
|
|
|
|
|
typedef struct _QWidgetRec {
|
|
|
|
CorePart core;
|
|
|
|
QWidgetPart qwidget;
|
|
|
|
} QWidgetRec;
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
void reparentChildrenOf(TQWidget* parent)
|
|
|
|
{
|
|
|
|
|
|
|
|
if ( !parent->children() )
|
|
|
|
return; // nothing to do
|
|
|
|
|
|
|
|
for ( TQObjectListIt it( *parent->children() ); it.current(); ++it ) {
|
|
|
|
if ( it.current()->isWidgetType() ) {
|
|
|
|
TQWidget* widget = (TQWidget*)it.current();
|
|
|
|
XReparentWindow( qt_xdisplay(),
|
|
|
|
widget->winId(),
|
|
|
|
parent->winId(),
|
|
|
|
widget->x(),
|
|
|
|
widget->y() );
|
|
|
|
if ( widget->isVisible() )
|
|
|
|
XMapWindow( qt_xdisplay(), widget->winId() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void qwidget_realize(
|
|
|
|
Widget widget,
|
|
|
|
XtValueMask* mask,
|
|
|
|
XSetWindowAttributes* attributes
|
|
|
|
)
|
|
|
|
{
|
|
|
|
widgetClassRec.core_class.realize(widget, mask, attributes);
|
|
|
|
KXtWidget* qxtw = ((QWidgetRec*)widget)->qwidget.qxtwidget;
|
|
|
|
if (XtWindow(widget) != qxtw->winId()) {
|
|
|
|
qxtw->create(XtWindow(widget), FALSE, FALSE);
|
|
|
|
reparentChildrenOf(qxtw);
|
|
|
|
}
|
|
|
|
qxtw->show();
|
|
|
|
XMapWindow( qt_xdisplay(), qxtw->winId() );
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
QWidgetClassRec qwidgetClassRec = {
|
|
|
|
{ /* core fields */
|
|
|
|
/* superclass */ (WidgetClass) &widgetClassRec,
|
|
|
|
/* class_name */ (char*)TQWIDGET_OBJECT_NAME_STRING,
|
|
|
|
/* widget_size */ sizeof(QWidgetRec),
|
|
|
|
/* class_initialize */ 0,
|
|
|
|
/* class_part_initialize */ 0,
|
|
|
|
/* class_inited */ FALSE,
|
|
|
|
/* initialize */ 0,
|
|
|
|
/* initialize_hook */ 0,
|
|
|
|
/* realize */ qwidget_realize,
|
|
|
|
/* actions */ 0,
|
|
|
|
/* num_actions */ 0,
|
|
|
|
/* resources */ 0,
|
|
|
|
/* num_resources */ 0,
|
|
|
|
/* xrm_class */ NULLQUARK,
|
|
|
|
/* compress_motion */ TRUE,
|
|
|
|
/* compress_exposure */ TRUE,
|
|
|
|
/* compress_enterleave */ TRUE,
|
|
|
|
/* visible_interest */ FALSE,
|
|
|
|
/* destroy */ 0,
|
|
|
|
/* resize */ XtInheritResize,
|
|
|
|
/* expose */ XtInheritExpose,
|
|
|
|
/* set_values */ 0,
|
|
|
|
/* set_values_hook */ 0,
|
|
|
|
/* set_values_almost */ XtInheritSetValuesAlmost,
|
|
|
|
/* get_values_hook */ 0,
|
|
|
|
/* accept_focus */ XtInheritAcceptFocus,
|
|
|
|
/* version */ XtVersion,
|
|
|
|
/* callback_private */ 0,
|
|
|
|
/* tm_table */ XtInheritTranslations,
|
|
|
|
/* query_geometry */ XtInheritQueryGeometry,
|
|
|
|
/* display_accelerator */ XtInheritDisplayAccelerator,
|
|
|
|
/* extension */ 0
|
|
|
|
},
|
|
|
|
{ /* qwidget fields */
|
|
|
|
/* empty */ 0
|
|
|
|
}
|
|
|
|
};
|
|
|
|
static WidgetClass qWidgetClass = (WidgetClass)&qwidgetClassRec;
|
|
|
|
|
|
|
|
static bool filters_installed = FALSE;
|
|
|
|
static KXtApplication* qxtapp = 0;
|
|
|
|
static XtAppContext appcon;
|
|
|
|
|
|
|
|
static
|
|
|
|
Boolean qt_event_handler_wrapper( XEvent* event )
|
|
|
|
{
|
|
|
|
return (Boolean)qt_event_handler( event );
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void installXtEventFilters()
|
|
|
|
{
|
|
|
|
if (filters_installed) return;
|
|
|
|
// Get Xt out of our face - install filter on every event type
|
|
|
|
for (int et=2; et < LASTEvent; et++) {
|
|
|
|
qt_np_cascade_event_handler[et] = XtSetEventDispatcher(
|
|
|
|
qt_xdisplay(), et, qt_event_handler_wrapper );
|
|
|
|
}
|
|
|
|
filters_installed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void removeXtEventFilters()
|
|
|
|
{
|
|
|
|
if (!filters_installed) return;
|
|
|
|
// We aren't needed any more... slink back into the shadows.
|
|
|
|
for (int et=2; et < LASTEvent; et++) {
|
|
|
|
XtSetEventDispatcher(
|
|
|
|
qt_xdisplay(), et, qt_np_cascade_event_handler[et] );
|
|
|
|
}
|
|
|
|
filters_installed = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// When we are in an event loop of TQApplication rather than the browser's
|
|
|
|
// event loop (eg. for a modal dialog), we still send events to Xt.
|
|
|
|
static
|
|
|
|
void np_event_proc( XEvent* e )
|
|
|
|
{
|
|
|
|
Widget xtw = XtWindowToWidget( e->xany.display, e->xany.window );
|
|
|
|
if ( xtw && tqApp->loopLevel() > 0 ) {
|
|
|
|
// Allow Xt to process the event
|
|
|
|
qt_np_cascade_event_handler[e->type]( e );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void np_set_timer( int interval )
|
|
|
|
{
|
|
|
|
// Ensure we only have one timeout in progress - TQApplication is
|
|
|
|
// computing the one amount of time we need to wait.
|
|
|
|
if ( qt_np_timerid ) {
|
|
|
|
XtRemoveTimeOut( qt_np_timerid );
|
|
|
|
}
|
|
|
|
qt_np_timerid = XtAppAddTimeOut(appcon, interval,
|
|
|
|
(XtTimerCallbackProc)qt_np_timeout, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void np_do_timers( void*, void* )
|
|
|
|
{
|
|
|
|
qt_np_timerid = 0; // It's us, and we just expired, that's why we are here.
|
|
|
|
|
|
|
|
qt_activate_timers();
|
|
|
|
|
|
|
|
timeval *tm = qt_wait_timer();
|
|
|
|
|
|
|
|
if (tm) {
|
|
|
|
int interval = QMIN(tm->tv_sec,INT_MAX/1000)*1000 + tm->tv_usec/1000;
|
|
|
|
np_set_timer( interval );
|
|
|
|
}
|
|
|
|
qxtapp->sendPostedEvents();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class KXtApplication qxt.h
|
|
|
|
\brief Allows mixing of Xt/Motif and Qt widgets.
|
|
|
|
|
|
|
|
\extension Xt/Motif
|
|
|
|
|
|
|
|
The KXtApplication and KXtWidget classes allow old Xt or Motif widgets
|
|
|
|
to be used in new Qt applications. They also allow Qt widgets to
|
|
|
|
be used in primarily Xt/Motif applications. The facility is intended
|
|
|
|
to aid migration from Xt/Motif to the more comfortable Qt system.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static bool my_xt;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a TQApplication and initializes the Xt toolkit.
|
|
|
|
The \a appclass, \a options, \a num_options, and \a resources
|
|
|
|
arguments are passed on to XtAppSetFallbackResources and
|
|
|
|
XtDisplayInitialize.
|
|
|
|
|
|
|
|
Use this constructor when writing a new Qt application which
|
|
|
|
needs to use some existing Xt/Motif widgets.
|
|
|
|
*/
|
|
|
|
KXtApplication::KXtApplication(int& argc, char** argv,
|
|
|
|
const TQCString& rAppName, bool allowStyles, bool GUIenabled,
|
|
|
|
XrmOptionDescRec *options, int num_options,
|
|
|
|
char** resources)
|
|
|
|
: KApplication(argc, argv, rAppName, allowStyles, GUIenabled)
|
|
|
|
{
|
|
|
|
my_xt = TRUE;
|
|
|
|
|
|
|
|
XtToolkitInitialize();
|
|
|
|
appcon = XtCreateApplicationContext();
|
|
|
|
if (resources) XtAppSetFallbackResources(appcon, (char**)resources);
|
|
|
|
XtDisplayInitialize(appcon, qt_xdisplay(), name(), rAppName, options,
|
|
|
|
num_options, &argc, argv);
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a TQApplication from the \a display of an already-initialized
|
|
|
|
Xt application.
|
|
|
|
|
|
|
|
Use this constructor when introducing Qt widgets into an existing
|
|
|
|
Xt/Motif application.
|
|
|
|
*/
|
|
|
|
KXtApplication::KXtApplication(Display* dpy, int& argc, char** argv,
|
|
|
|
const TQCString& rAppName, bool allowStyles, bool GUIenabled)
|
|
|
|
: KApplication(dpy, argc, argv, rAppName, allowStyles, GUIenabled)
|
|
|
|
{
|
|
|
|
my_xt = FALSE;
|
|
|
|
init();
|
|
|
|
appcon = XtDisplayToApplicationContext(dpy);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Destructs the application. Does not close the Xt toolkit.
|
|
|
|
*/
|
|
|
|
KXtApplication::~KXtApplication()
|
|
|
|
{
|
|
|
|
Q_ASSERT(qxtapp==this);
|
|
|
|
removeXtEventFilters();
|
|
|
|
qxtapp = 0;
|
|
|
|
|
|
|
|
// the manpage says: "or just exit", that's what we do to avoid
|
|
|
|
// double closing of the display
|
|
|
|
// if (my_xt) {
|
|
|
|
// XtDestroyApplicationContext(appcon);
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
void KXtApplication::init()
|
|
|
|
{
|
|
|
|
Q_ASSERT(qxtapp==0);
|
|
|
|
qxtapp = this;
|
|
|
|
installXtEventFilters();
|
|
|
|
qt_np_add_timeoutcb(np_do_timers);
|
|
|
|
qt_np_add_timer_setter(np_set_timer);
|
|
|
|
qt_np_add_event_proc(np_event_proc);
|
|
|
|
qt_np_count++;
|
|
|
|
/* TQTimer *timer = new TQTimer( this );
|
|
|
|
timer->start(500);*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\class KXtWidget qxt.h
|
|
|
|
\brief Allows mixing of Xt/Motif and Qt widgets.
|
|
|
|
|
|
|
|
\extension Xt/Motif
|
|
|
|
|
|
|
|
KXtWidget acts as a bridge between Xt and Qt. For utilizing old
|
|
|
|
Xt widgets, it can be a QWidget
|
|
|
|
based on a Xt widget class. For including Qt widgets in an existing
|
|
|
|
Xt/Motif application, it can be a special Xt widget class that is
|
|
|
|
a TQWidget. See the constructors for the different behaviors.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void KXtWidget::init(const char* name, WidgetClass widget_class,
|
|
|
|
Widget parent, TQWidget* qparent,
|
|
|
|
ArgList args, Cardinal num_args,
|
|
|
|
bool managed)
|
|
|
|
{
|
|
|
|
need_reroot=FALSE;
|
|
|
|
xtparent = 0;
|
|
|
|
if (parent ) {
|
|
|
|
Q_ASSERT(!qparent);
|
|
|
|
xtw = XtCreateWidget(name, widget_class, parent, args, num_args);
|
|
|
|
if ( widget_class == qWidgetClass )
|
|
|
|
((QWidgetRec*)xtw)->qwidget.qxtwidget = this;
|
|
|
|
xtparent = parent;
|
|
|
|
if (managed)
|
|
|
|
XtManageChild(xtw);
|
|
|
|
} else {
|
|
|
|
Q_ASSERT(!managed);
|
|
|
|
|
|
|
|
String n, c;
|
|
|
|
XtGetApplicationNameAndClass(qt_xdisplay(), &n, &c);
|
|
|
|
xtw = XtAppCreateShell(n, c, widget_class, qt_xdisplay(),
|
|
|
|
args, num_args);
|
|
|
|
if ( widget_class == qWidgetClass )
|
|
|
|
((QWidgetRec*)xtw)->qwidget.qxtwidget = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( qparent ) {
|
|
|
|
XtResizeWidget( xtw, 100, 100, 0 );
|
|
|
|
XtSetMappedWhenManaged(xtw, False);
|
|
|
|
XtRealizeWidget(xtw);
|
|
|
|
XSync(qt_xdisplay(), False); // I want all windows to be created now
|
|
|
|
XReparentWindow(qt_xdisplay(), XtWindow(xtw), qparent->winId(), x(), y());
|
|
|
|
XtSetMappedWhenManaged(xtw, True);
|
|
|
|
need_reroot=TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Arg reqargs[20];
|
|
|
|
Cardinal nargs=0;
|
|
|
|
XtSetArg(reqargs[nargs], XtNx, x()); nargs++;
|
|
|
|
XtSetArg(reqargs[nargs], XtNy, y()); nargs++;
|
|
|
|
XtSetArg(reqargs[nargs], XtNwidth, width()); nargs++;
|
|
|
|
XtSetArg(reqargs[nargs], XtNheight, height()); nargs++;
|
|
|
|
//XtSetArg(reqargs[nargs], "mappedWhenManaged", False); nargs++;
|
|
|
|
XtSetValues(xtw, reqargs, nargs);
|
|
|
|
|
|
|
|
//#### destroy(); MLK
|
|
|
|
|
|
|
|
if (!parent || XtIsRealized(parent))
|
|
|
|
XtRealizeWidget(xtw);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a KXtWidget of the special Xt widget class known as
|
|
|
|
TQWIDGET_OBJECT_NAME_STRING to the resource manager.
|
|
|
|
|
|
|
|
Use this constructor to utilize Qt widgets in an Xt/Motif
|
|
|
|
application. The KXtWidget is a TQWidget, so you can create
|
|
|
|
subwidgets, layouts, etc. using Qt functionality.
|
|
|
|
*/
|
|
|
|
KXtWidget::KXtWidget(const char* name, Widget parent, bool managed) :
|
|
|
|
TQWidget( 0, name, WResizeNoErase )
|
|
|
|
{
|
|
|
|
init(name, qWidgetClass, parent, 0, 0, 0, managed);
|
|
|
|
Arg reqargs[20];
|
|
|
|
Cardinal nargs=0;
|
|
|
|
XtSetArg(reqargs[nargs], XtNborderWidth, 0);
|
|
|
|
nargs++;
|
|
|
|
XtSetValues(xtw, reqargs, nargs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Constructs a KXtWidget of the given \a widget_class.
|
|
|
|
|
|
|
|
Use this constructor to utilize Xt or Motif widgets in a Qt
|
|
|
|
application. The KXtWidget looks and behaves
|
|
|
|
like the Xt class, but can be used like any TQWidget.
|
|
|
|
|
|
|
|
Note that Xt requires that the most toplevel Xt widget is a shell.
|
|
|
|
That means, if \a parent is a KXtWidget, the \a widget_class can be
|
|
|
|
of any kind. If there isn't a parent or the parent is just a normal
|
|
|
|
TQWidget, \a widget_class should be something like \c
|
|
|
|
topLevelShellWidgetClass.
|
|
|
|
|
|
|
|
If the \a managed parameter is TRUE and \a parent in not NULL,
|
|
|
|
XtManageChild it used to manage the child.
|
|
|
|
*/
|
|
|
|
KXtWidget::KXtWidget(const char* name, WidgetClass widget_class,
|
|
|
|
TQWidget *parent, ArgList args, Cardinal num_args,
|
|
|
|
bool managed) :
|
|
|
|
TQWidget( parent, name, WResizeNoErase )
|
|
|
|
{
|
|
|
|
if ( !parent )
|
|
|
|
init(name, widget_class, 0, 0, args, num_args, managed);
|
|
|
|
else if ( parent->inherits("KXtWidget") )
|
|
|
|
init(name, widget_class, ( (KXtWidget*)parent)->xtw , 0, args, num_args, managed);
|
|
|
|
else
|
|
|
|
init(name, widget_class, 0, parent, args, num_args, managed);
|
|
|
|
create(XtWindow(xtw), FALSE, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Destructs the KXtWidget.
|
|
|
|
*/
|
|
|
|
KXtWidget::~KXtWidget()
|
|
|
|
{
|
|
|
|
// Delete children first, as Xt will destroy their windows
|
|
|
|
//
|
|
|
|
TQObjectList* list = queryList(TQWIDGET_OBJECT_NAME_STRING, 0, FALSE, FALSE);
|
|
|
|
if ( list ) {
|
|
|
|
TQWidget* c;
|
|
|
|
TQObjectListIt it( *list );
|
|
|
|
while ( (c = (TQWidget*)it.current()) ) {
|
|
|
|
delete c;
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
delete list;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( need_reroot ) {
|
|
|
|
hide();
|
|
|
|
XReparentWindow(qt_xdisplay(), winId(), tqApp->desktop()->winId(),
|
|
|
|
x(), y());
|
|
|
|
}
|
|
|
|
|
|
|
|
XtDestroyWidget(xtw);
|
|
|
|
destroy( FALSE, FALSE );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\fn Widget KXtWidget::xtWidget() const
|
|
|
|
Returns the Xt widget equivalent for the Qt widget.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Reimplemented to produce the Xt effect of getting focus when the
|
|
|
|
mouse enters the widget. <em>This may be changed.</em>
|
|
|
|
*/
|
|
|
|
bool KXtWidget::x11Event( XEvent * e )
|
|
|
|
{
|
|
|
|
if ( e->type == EnterNotify ) {
|
|
|
|
if ( xtparent )
|
|
|
|
setActiveWindow();
|
|
|
|
}
|
|
|
|
return TQWidget::x11Event( e );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Implement a degree of focus handling for Xt widgets.
|
|
|
|
*/
|
|
|
|
void KXtWidget::setActiveWindow()
|
|
|
|
{
|
|
|
|
if ( xtparent ) {
|
|
|
|
if ( !TQWidget::isActiveWindow() && isActiveWindow() ) {
|
|
|
|
XFocusChangeEvent e;
|
|
|
|
e.type = FocusIn;
|
|
|
|
e.window = winId();
|
|
|
|
e.mode = NotifyNormal;
|
|
|
|
e.detail = NotifyInferior;
|
|
|
|
XSendEvent( qt_xdisplay(), e.window, TRUE, NoEventMask, (XEvent*)&e );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TQWidget::setActiveWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Different from TQWidget::isActiveWindow()
|
|
|
|
*/
|
|
|
|
bool KXtWidget::isActiveWindow() const
|
|
|
|
{
|
|
|
|
Window win;
|
|
|
|
int revert;
|
|
|
|
XGetInputFocus( qt_xdisplay(), &win, &revert );
|
|
|
|
|
|
|
|
if ( win == None) return FALSE;
|
|
|
|
|
|
|
|
TQWidget *w = find( (WId)win );
|
|
|
|
if ( w ) {
|
|
|
|
// We know that window
|
|
|
|
return w->topLevelWidget() == topLevelWidget();
|
|
|
|
} else {
|
|
|
|
// Window still may be a parent (if top-level is foreign window)
|
|
|
|
Window root, parent;
|
|
|
|
Window cursor = winId();
|
|
|
|
Window *ch;
|
|
|
|
unsigned int nch;
|
|
|
|
while ( XQueryTree(qt_xdisplay(), cursor, &root, &parent, &ch, &nch) ) {
|
|
|
|
if (ch) XFree( (char*)ch);
|
|
|
|
if ( parent == win ) return TRUE;
|
|
|
|
if ( parent == root ) return FALSE;
|
|
|
|
cursor = parent;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!\reimp
|
|
|
|
*/
|
|
|
|
void KXtWidget::moveEvent( TQMoveEvent* )
|
|
|
|
{
|
|
|
|
if ( xtparent )
|
|
|
|
return;
|
|
|
|
XConfigureEvent c;
|
|
|
|
c.type = ConfigureNotify;
|
|
|
|
c.event = winId();
|
|
|
|
c.window = winId();
|
|
|
|
c.x = x();
|
|
|
|
c.y = y();
|
|
|
|
c.width = width();
|
|
|
|
c.height = height();
|
|
|
|
c.border_width = 0;
|
|
|
|
XSendEvent( qt_xdisplay(), c.event, TRUE, NoEventMask, (XEvent*)&c );
|
|
|
|
XtMoveWidget( xtw, x(), y() );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!\reimp
|
|
|
|
*/
|
|
|
|
void KXtWidget::resizeEvent( TQResizeEvent* )
|
|
|
|
{
|
|
|
|
if ( xtparent )
|
|
|
|
return;
|
|
|
|
XtWidgetGeometry preferred;
|
|
|
|
(void ) XtQueryGeometry( xtw, 0, &preferred );
|
|
|
|
XConfigureEvent c;
|
|
|
|
c.type = ConfigureNotify;
|
|
|
|
c.event = winId();
|
|
|
|
c.window = winId();
|
|
|
|
c.x = x();
|
|
|
|
c.y = y();
|
|
|
|
c.width = width();
|
|
|
|
c.height = height();
|
|
|
|
c.border_width = 0;
|
|
|
|
XSendEvent( qt_xdisplay(), c.event, TRUE, NoEventMask, (XEvent*)&c );
|
|
|
|
XtResizeWidget( xtw, width(), height(), preferred.border_width );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kxt.moc"
|
|
|
|
|
|
|
|
#endif
|