00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "qplatformdefs.h"
00031
00032 #include "qcolormap.h"
00033 #include "qdesktopwidget.h"
00034 #include "qapplication.h"
00035 #include "qapplication_p.h"
00036 #include "qcursor.h"
00037 #include "qwidget.h"
00038 #include "qbitarray.h"
00039 #include "qpainter.h"
00040 #include "qfile.h"
00041 #include "qpixmapcache.h"
00042 #include "qdatetime.h"
00043 #include "qtextcodec.h"
00044 #include "qdatastream.h"
00045 #include "qbuffer.h"
00046 #include "qsocketnotifier.h"
00047 #include "qsessionmanager.h"
00048 #include "qclipboard.h"
00049 #include "qwhatsthis.h"
00050 #include "qsettings.h"
00051 #include "qstylefactory.h"
00052 #include "qfileinfo.h"
00053 #include "qhash.h"
00054 #include "qevent.h"
00055 #include "qevent_p.h"
00056 #include "qvarlengtharray.h"
00057 #include "qdebug.h"
00058 #include <private/qunicodetables_p.h>
00059 #include <private/qcrashhandler_p.h>
00060 #include <private/qcolor_p.h>
00061 #include <private/qcursor_p.h>
00062 #include "qstyle.h"
00063 #include "qmetaobject.h"
00064
00065 #if !defined(QT_NO_GLIB)
00066 # include "qguieventdispatcher_glib_p.h"
00067 #endif
00068 #include "qeventdispatcher_x11_p.h"
00069 #include <private/qpaintengine_x11_p.h>
00070
00071 #include <private/qkeymapper_p.h>
00072
00073
00074 #ifndef QT_NO_IM
00075 #include "qinputcontext.h"
00076 #include "qinputcontextfactory.h"
00077 #endif // QT_NO_IM
00078
00079 #ifndef QT_NO_XFIXES
00080 #include <X11/extensions/Xfixes.h>
00081 #endif // QT_NO_XFIXES
00082
00083 #include "qt_x11_p.h"
00084 #include "qx11info_x11.h"
00085
00086 #define XK_MISCELLANY
00087 #include <X11/keysymdef.h>
00088 #include <X11/extensions/XI.h>
00089
00090 #include <stdlib.h>
00091 #include <string.h>
00092 #include <ctype.h>
00093 #include <locale.h>
00094
00095 #include "qwidget_p.h"
00096
00097 #include <private/qbackingstore_p.h>
00098
00099
00100 #ifdef X_NOT_BROKEN
00101
00102
00103
00104
00105
00106
00107
00108 # ifndef setlocale
00109 extern "C" char *_Xsetlocale(int category, const char *locale);
00110 char *_Xsetlocale(int category, const char *locale)
00111 {
00112
00113 return setlocale(category,locale);
00114 }
00115 # endif // setlocale
00116 #endif // X_NOT_BROKEN
00117
00118
00119
00120 static const char * x11_atomnames = {
00121
00122 "WM_PROTOCOLS\0"
00123 "WM_DELETE_WINDOW\0"
00124 "WM_TAKE_FOCUS\0"
00125 "_NET_WM_PING\0"
00126 "_NET_WM_CONTEXT_HELP\0"
00127
00128
00129 "WM_STATE\0"
00130 "WM_CHANGE_STATE\0"
00131
00132
00133 "WM_CLIENT_LEADER\0"
00134 "WM_WINDOW_ROLE\0"
00135 "SM_CLIENT_ID\0"
00136
00137
00138 "CLIPBOARD\0"
00139 "INCR\0"
00140 "TARGETS\0"
00141 "MULTIPLE\0"
00142 "TIMESTAMP\0"
00143 "CLIP_TEMPORARY\0"
00144 "_QT_SELECTION\0"
00145 "_QT_CLIPBOARD_SENTINEL\0"
00146 "_QT_SELECTION_SENTINEL\0"
00147
00148 "RESOURCE_MANAGER\0"
00149
00150 "_XSETROOT_ID\0"
00151
00152 "_QT_SCROLL_DONE\0"
00153 "_QT_INPUT_ENCODING\0"
00154
00155 "_MOTIF_WM_HINTS\0"
00156
00157 "DTWM_IS_RUNNING\0"
00158 "KDE_FULL_SESSION\0"
00159 "KWIN_RUNNING\0"
00160 "KWM_RUNNING\0"
00161 "GNOME_BACKGROUND_PROPERTIES\0"
00162 "ENLIGHTENMENT_DESKTOP\0"
00163 "_SGI_DESKS_MANAGER\0"
00164
00165
00166 "_NET_SUPPORTED\0"
00167 "_NET_VIRTUAL_ROOTS\0"
00168 "_NET_WORKAREA\0"
00169
00170 "_NET_WM_NAME\0"
00171 "_NET_WM_ICON_NAME\0"
00172 "_NET_WM_ICON\0"
00173
00174 "_NET_WM_PID\0"
00175
00176 "_NET_WM_WINDOW_OPACITY\0"
00177
00178 "_NET_WM_STATE\0"
00179 "_NET_WM_STATE_ABOVE\0"
00180 "_NET_WM_STATE_FULLSCREEN\0"
00181 "_NET_WM_STATE_MAXIMIZED_HORZ\0"
00182 "_NET_WM_STATE_MAXIMIZED_VERT\0"
00183 "_NET_WM_STATE_MODAL\0"
00184 "_NET_WM_STATE_STAYS_ON_TOP\0"
00185
00186 "_NET_WM_USER_TIME\0"
00187 "_NET_WM_FULL_PLACEMENT\0"
00188
00189 "_NET_WM_WINDOW_TYPE\0"
00190 "_NET_WM_WINDOW_TYPE_DIALOG\0"
00191 "_NET_WM_WINDOW_TYPE_MENU\0"
00192 "_NET_WM_WINDOW_TYPE_NORMAL\0"
00193 "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
00194 "_NET_WM_WINDOW_TYPE_SPLASH\0"
00195 "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
00196 "_NET_WM_WINDOW_TYPE_UTILITY\0"
00197
00198 "_KDE_NET_WM_FRAME_STRUT\0"
00199
00200 "_NET_STARTUP_INFO\0"
00201 "_NET_STARTUP_INFO_BEGIN\0"
00202
00203 "_NET_SUPPORTING_WM_CHECK\0"
00204
00205
00206 "COMPOUND_TEXT\0"
00207 "TEXT\0"
00208 "UTF8_STRING\0"
00209
00210
00211 "XdndEnter\0"
00212 "XdndPosition\0"
00213 "XdndStatus\0"
00214 "XdndLeave\0"
00215 "XdndDrop\0"
00216 "XdndFinished\0"
00217 "XdndTypeList\0"
00218 "XdndActionList\0"
00219
00220 "XdndSelection\0"
00221
00222 "XdndAware\0"
00223 "XdndProxy\0"
00224
00225 "XdndActionCopy\0"
00226 "XdndActionLink\0"
00227 "XdndActionMove\0"
00228 "XdndActionPrivate\0"
00229
00230
00231 "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
00232 "_MOTIF_DRAG_INITIATOR_INFO\0"
00233 "_MOTIF_DRAG_RECEIVER_INFO\0"
00234 "_MOTIF_DRAG_WINDOW\0"
00235 "_MOTIF_DRAG_TARGETS\0"
00236
00237 "XmTRANSFER_SUCCESS\0"
00238 "XmTRANSFER_FAILURE\0"
00239
00240
00241 "_XKB_RULES_NAMES\0"
00242 };
00243
00244 Q_GUI_EXPORT QX11Data *qt_x11Data = 0;
00245
00246
00247
00248
00249 static const char *appName = 0;
00250 static const char *appClass = 0;
00251 static const char *appFont = 0;
00252 static const char *appBGCol = 0;
00253 static const char *appFGCol = 0;
00254 static const char *appBTNCol = 0;
00255 static const char *mwGeometry = 0;
00256 static const char *mwTitle = 0;
00257 char *qt_ximServer = 0;
00258 #if 0
00259 static bool noxim = false;
00260 #endif
00261 static bool appSync = false;
00262 #if defined(QT_DEBUG)
00263 static bool appNoGrab = false;
00264 static bool appDoGrab = false;
00265 #endif
00266 static bool app_save_rootinfo = false;
00267 static bool app_do_modal = false;
00268 static Window curWin = 0;
00269
00270
00271 bool qt_broken_wm = false;
00272 static void qt_detect_broken_window_manager();
00273
00274
00275
00276 extern void qt_desktopwidget_update_workarea();
00277
00278
00279
00280
00281 uchar qt_alt_mask = 0;
00282 uchar qt_meta_mask = 0;
00283 uchar qt_super_mask = 0;
00284 uchar qt_hyper_mask = 0;
00285 uchar qt_mode_switch_mask = 0;
00286
00287
00288 bool qt_use_rtl_extensions = false;
00289
00290 static Window mouseActWindow = 0;
00291 static Qt::MouseButton mouseButtonPressed = Qt::NoButton;
00292 static Qt::MouseButtons mouseButtonState = Qt::NoButton;
00293 static Time mouseButtonPressTime = 0;
00294 static short mouseXPos, mouseYPos;
00295 static short mouseGlobalXPos, mouseGlobalYPos;
00296
00297 extern QWidgetList *qt_modal_stack;
00298
00299
00300 static Window pressed_window = XNone;
00301
00302
00303 static bool replayPopupMouseEvent = false;
00304 static bool popupGrabOk;
00305
00306 bool qt_sm_blockUserInput = false;
00307
00308 bool qt_reuse_double_buffer = true;
00309
00310 Q_GUI_EXPORT int qt_xfocusout_grab_counter = 0;
00311
00312 #if !defined (QT_NO_TABLET)
00313 Q_GLOBAL_STATIC(QTabletDeviceDataList, tablet_devices)
00314 QTabletDeviceDataList *qt_tablet_devices()
00315 {
00316 return tablet_devices();
00317 }
00318
00319 extern bool qt_tabletChokeMouse;
00320 #endif
00321
00322 static bool qt_x11EventFilter(XEvent* ev)
00323 {
00324 long unused;
00325 if (qApp->filterEvent(ev, &unused))
00326 return true;
00327 return qApp->x11EventFilter(ev);
00328 }
00329
00330 #if !defined(QT_NO_XIM)
00331 XIMStyle qt_xim_preferred_style = 0;
00332 #endif
00333 int qt_ximComposingKeycode=0;
00334 QTextCodec * qt_input_mapper = 0;
00335
00336 extern bool qt_check_clipboard_sentinel();
00337 extern bool qt_check_selection_sentinel();
00338
00339 static void qt_save_rootinfo();
00340 Q_GUI_EXPORT bool qt_try_modal(QWidget *, XEvent *);
00341
00342 QWidget *qt_button_down = 0;
00343 static QWidget *qt_popup_down = 0;
00344
00345 extern bool qt_xdnd_dragging;
00346
00347
00348 extern bool qt_is_gui_used;
00349 extern bool qt_app_has_font;
00350
00351 class QETWidget : public QWidget
00352 {
00353 public:
00354 bool translateMouseEvent(const XEvent *);
00355 void translatePaintEvent(const XEvent *);
00356 bool translateConfigEvent(const XEvent *);
00357 bool translateCloseEvent(const XEvent *);
00358 bool translateScrollDoneEvent(const XEvent *);
00359 bool translateWheelEvent(int global_x, int global_y, int delta, Qt::MouseButtons buttons,
00360 Qt::KeyboardModifiers modifiers, Qt::Orientation orient);
00361 #if !defined (QT_NO_TABLET)
00362 bool translateXinputEvent(const XEvent*, const QTabletDeviceData *tablet);
00363 #endif
00364 bool translatePropertyEvent(const XEvent *);
00365 };
00366
00367
00368 void QApplicationPrivate::createEventDispatcher()
00369 {
00370 Q_Q(QApplication);
00371 #if !defined(QT_NO_GLIB)
00372 if (qgetenv("QT_NO_GLIB").isEmpty())
00373 eventDispatcher = (q->type() != QApplication::Tty
00374 ? new QGuiEventDispatcherGlib(q)
00375 : new QEventDispatcherGlib(q));
00376 else
00377 #endif
00378 eventDispatcher = (q->type() != QApplication::Tty
00379 ? new QEventDispatcherX11(q)
00380 : new QEventDispatcherUNIX(q));
00381 }
00382
00383
00384
00385
00386
00387 #if defined(Q_C_CALLBACKS)
00388 extern "C" {
00389 #endif
00390
00391 static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
00392 static int (*original_xio_errhandler)(Display *dpy);
00393
00394 static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
00395 {
00396 if (err->error_code == BadWindow) {
00397 X11->seen_badwindow = true;
00398 if (err->request_code == 25 && X11->xdndHandleBadwindow())
00399 return 0;
00400 if (X11->ignore_badwindow)
00401 return 0;
00402 } else if (err->request_code == X11->xinput_major
00403 && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
00404 && err->minor_code == 3 ) {
00405 return 0;
00406 } else if (err->error_code == BadMatch && err->request_code == 42 ) {
00407 return 0;
00408 }
00409
00410 char errstr[256];
00411 XGetErrorText( dpy, err->error_code, errstr, 256 );
00412 char buffer[256];
00413 char request_str[256];
00414 qsnprintf(buffer, 256, "%d", err->request_code);
00415 XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256);
00416 if (err->request_code < 128) {
00417
00418 qWarning( "X Error: %s %d\n"
00419 " Major opcode: %d (%s)\n"
00420 " Resource id: 0x%lx",
00421 errstr, err->error_code,
00422 err->request_code,
00423 request_str,
00424 err->resourceid );
00425 } else {
00426
00427 const char *extensionName = 0;
00428 if (err->request_code == X11->xrender_major)
00429 extensionName = "RENDER";
00430 else if (err->request_code == X11->xrandr_major)
00431 extensionName = "RANDR";
00432 else if (err->request_code == X11->xinput_major)
00433 extensionName = "XInputExtension";
00434
00435 char minor_str[256];
00436 if (extensionName) {
00437 qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code);
00438 XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256);
00439 } else {
00440 extensionName = "Uknown extension";
00441 qsnprintf(minor_str, 256, "Unknown request");
00442 }
00443 qWarning( "X Error: %s %d\n"
00444 " Extension: %d (%s)\n"
00445 " Minor opcode: %d (%s)\n"
00446 " Resource id: 0x%lx",
00447 errstr, err->error_code,
00448 err->request_code,
00449 extensionName,
00450 err->minor_code,
00451 minor_str,
00452 err->resourceid );
00453 }
00454
00455
00456
00457
00458 return 0;
00459 }
00460
00461
00462 static int qt_xio_errhandler(Display *)
00463 {
00464 qWarning("%s: Fatal IO error: client killed", appName);
00465 QApplicationPrivate::reset_instance_pointer();
00466 exit(1);
00467
00468
00469 return 0;
00470 }
00471
00472 #if defined(Q_C_CALLBACKS)
00473 }
00474 #endif
00475
00476
00477 static void qt_x11_create_intern_atoms()
00478 {
00479 const char *names[QX11Data::NAtoms];
00480 const char *ptr = x11_atomnames;
00481
00482 int i = 0;
00483 while (*ptr) {
00484 names[i++] = ptr;
00485 while (*ptr)
00486 ++ptr;
00487 ++ptr;
00488 }
00489
00490 Q_ASSERT(i == QX11Data::NPredefinedAtoms);
00491
00492 QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
00493 settings_atom_name += XDisplayName(X11->displayName);
00494 names[i++] = settings_atom_name;
00495
00496 Q_ASSERT(i == QX11Data::NAtoms);
00497 #if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
00498 XInternAtoms(X11->display, (char **)names, i, False, X11->atoms);
00499 #else
00500 for (i = 0; i < QX11Data::NAtoms; ++i)
00501 X11->atoms[i] = XInternAtom(X11->display, (char *)names[i], False);
00502 #endif
00503 }
00504
00505 Q_GUI_EXPORT void qt_x11_apply_settings_in_all_apps()
00506 {
00507 QByteArray stamp;
00508 QDataStream s(&stamp, QIODevice::WriteOnly);
00509 s << QDateTime::currentDateTime();
00510
00511 XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
00512 ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
00513 PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
00514 }
00515
00519 bool QApplicationPrivate::x11_apply_settings()
00520 {
00521 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
00522
00523 settings.beginGroup(QLatin1String("Qt"));
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 QStringList strlist;
00546 int i;
00547 QPalette pal(Qt::black);
00548 int groupCount = 0;
00549 strlist = settings.value(QLatin1String("Palette/active")).toStringList();
00550 if (strlist.count() == QPalette::NColorRoles) {
00551 ++groupCount;
00552 for (i = 0; i < QPalette::NColorRoles; i++)
00553 pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
00554 QColor(strlist[i]));
00555 }
00556 strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
00557 if (strlist.count() == QPalette::NColorRoles) {
00558 ++groupCount;
00559 for (i = 0; i < QPalette::NColorRoles; i++)
00560 pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
00561 QColor(strlist[i]));
00562 }
00563 strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
00564 if (strlist.count() == QPalette::NColorRoles) {
00565 ++groupCount;
00566 for (i = 0; i < QPalette::NColorRoles; i++)
00567 pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
00568 QColor(strlist[i]));
00569 }
00570
00571 if (groupCount == QPalette::NColorGroups)
00572 QApplicationPrivate::setSystemPalette(pal);
00573
00574 if (!qt_app_has_font && !appFont) {
00575 QFont font(QApplication::font());
00576 QString str = settings.value(QLatin1String("font")).toString();
00577 if (!str.isEmpty()) {
00578 font.fromString(str);
00579 if (font != QApplication::font())
00580 QApplication::setFont(font);
00581 }
00582 }
00583
00584
00585 QString libpathkey =
00586 QString(QLatin1String("%1.%2/libraryPath"))
00587 .arg(QT_VERSION >> 16)
00588 .arg((QT_VERSION & 0xff00) >> 8);
00589 QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
00590 if (! pathlist.isEmpty()) {
00591 QStringList::ConstIterator it = pathlist.constBegin();
00592 while (it != pathlist.constEnd())
00593 QApplication::addLibraryPath(*it++);
00594 }
00595
00596
00597 QString stylename = settings.value(QLatin1String("style")).toString();
00598 if (QCoreApplication::startingUp()) {
00599 if (!stylename.isEmpty() && !QApplicationPrivate::styleOverride)
00600 QApplicationPrivate::styleOverride = new QString(stylename);
00601 } else {
00602 QApplication::setStyle(stylename);
00603 }
00604
00605 int num =
00606 settings.value(QLatin1String("doubleClickInterval"),
00607 QApplication::doubleClickInterval()).toInt();
00608 QApplication::setDoubleClickInterval(num);
00609
00610 num =
00611 settings.value(QLatin1String("cursorFlashTime"),
00612 QApplication::cursorFlashTime()).toInt();
00613 QApplication::setCursorFlashTime(num);
00614
00615 num =
00616 settings.value(QLatin1String("wheelScrollLines"),
00617 QApplication::wheelScrollLines()).toInt();
00618 QApplication::setWheelScrollLines(num);
00619
00620 QString colorspec = settings.value(QLatin1String("colorSpec"),
00621 QVariant(QLatin1String("default"))).toString();
00622 if (colorspec == QLatin1String("normal"))
00623 QApplication::setColorSpec(QApplication::NormalColor);
00624 else if (colorspec == QLatin1String("custom"))
00625 QApplication::setColorSpec(QApplication::CustomColor);
00626 else if (colorspec == QLatin1String("many"))
00627 QApplication::setColorSpec(QApplication::ManyColor);
00628 else if (colorspec != QLatin1String("default"))
00629 colorspec = QLatin1String("default");
00630
00631 QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
00632 QVariant(QLatin1String("none"))).toString();
00633 if (defaultcodec != QLatin1String("none")) {
00634 QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
00635 if (codec)
00636 QTextCodec::setCodecForTr(codec);
00637 }
00638
00639 int w = settings.value(QLatin1String("globalStrut/width")).toInt();
00640 int h = settings.value(QLatin1String("globalStrut/height")).toInt();
00641 QSize strut(w, h);
00642 if (strut.isValid())
00643 QApplication::setGlobalStrut(strut);
00644
00645 QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
00646 QApplication::setEffectEnabled(Qt::UI_General,
00647 effects.contains(QLatin1String("general")));
00648 QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
00649 effects.contains(QLatin1String("animatemenu")));
00650 QApplication::setEffectEnabled(Qt::UI_FadeMenu,
00651 effects.contains(QLatin1String("fademenu")));
00652 QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
00653 effects.contains(QLatin1String("animatecombo")));
00654 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
00655 effects.contains(QLatin1String("animatetooltip")));
00656 QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
00657 effects.contains(QLatin1String("fadetooltip")));
00658 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
00659 effects.contains(QLatin1String("animatetoolbox")));
00660
00661 settings.beginGroup(QLatin1String("Font Substitutions"));
00662 QStringList fontsubs = settings.childKeys();
00663 if (!fontsubs.isEmpty()) {
00664 QStringList::Iterator it = fontsubs.begin();
00665 for (; it != fontsubs.end(); ++it) {
00666 QString fam = *it;
00667 QStringList subs = settings.value(fam).toStringList();
00668 QFont::insertSubstitutions(fam, subs);
00669 }
00670 }
00671 settings.endGroup();
00672
00673 qt_broken_wm =
00674 settings.value(QLatin1String("brokenWindowManager"), qt_broken_wm).toBool();
00675
00676 qt_use_rtl_extensions =
00677 settings.value(QLatin1String("useRtlExtensions"), false).toBool();
00678
00679 qt_reuse_double_buffer =
00680 settings.value(QLatin1String("reuseDoubleBuffer"), true).toBool();
00681
00682 #ifndef QT_NO_XIM
00683 if (qt_xim_preferred_style == 0) {
00684 QString ximInputStyle = settings.value(QLatin1String("XIMInputStyle"),
00685 QVariant(QLatin1String("on the spot"))).toString().toLower();
00686 if (ximInputStyle == QLatin1String("on the spot"))
00687 qt_xim_preferred_style = XIMPreeditCallbacks | XIMStatusNothing;
00688 else if (ximInputStyle == QLatin1String("over the spot"))
00689 qt_xim_preferred_style = XIMPreeditPosition | XIMStatusNothing;
00690 else if (ximInputStyle == QLatin1String("off the spot"))
00691 qt_xim_preferred_style = XIMPreeditArea | XIMStatusArea;
00692 else if (ximInputStyle == QLatin1String("root"))
00693 qt_xim_preferred_style = XIMPreeditNothing | XIMStatusNothing;
00694 }
00695 #endif
00696 QStringList inputMethods = QInputContextFactory::keys();
00697 if (inputMethods.size() > 2 && inputMethods.contains(QLatin1String("imsw-multi"))) {
00698 X11->default_im = QLatin1String("imsw-multi");
00699 } else {
00700 X11->default_im = settings.value(QLatin1String("DefaultInputMethod"),
00701 QLatin1String("xim")).toString();
00702 }
00703
00704 settings.endGroup();
00705
00706 return true;
00707 }
00708
00709
00713 void QApplicationPrivate::reset_instance_pointer()
00714 { QApplication::self = 0; }
00715
00716
00717
00718
00719 static void qt_set_input_encoding()
00720 {
00721 Atom type;
00722 int format;
00723 ulong nitems, after = 1;
00724 const char *data = 0;
00725
00726 int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
00727 ATOM(_QT_INPUT_ENCODING), 0, 1024,
00728 False, XA_STRING, &type, &format, &nitems,
00729 &after, (unsigned char**)&data);
00730 if (e != Success || !nitems || type == XNone) {
00731
00732
00733
00734 qt_input_mapper = QTextCodec::codecForLocale();
00735
00736 } else {
00737 if (!qstricmp(data, "locale"))
00738 qt_input_mapper = QTextCodec::codecForLocale();
00739 else
00740 qt_input_mapper = QTextCodec::codecForName(data);
00741
00742 if(!qt_input_mapper)
00743 qt_input_mapper = QTextCodec::codecForName("ISO 8859-1");
00744 }
00745 if (qt_input_mapper && qt_input_mapper->mibEnum() == 11)
00746 qt_input_mapper = QTextCodec::codecForName("ISO 8859-8-I");
00747 if(data)
00748 XFree((char *)data);
00749 }
00750
00751
00752
00753 static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
00754 const char* bg = 0, const char* button = 0)
00755 {
00756
00757 QString resFont, resFG, resBG, resEF, sysFont, selectBackground, selectForeground;
00758
00759 QApplication::setEffectEnabled(Qt::UI_General, false);
00760 QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false);
00761 QApplication::setEffectEnabled(Qt::UI_FadeMenu, false);
00762 QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
00763 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, false);
00764 QApplication::setEffectEnabled(Qt::UI_FadeTooltip, false);
00765 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, false);
00766
00767 bool paletteAlreadySet = false;
00768 if (QApplication::desktopSettingsAware()) {
00769
00770 QApplicationPrivate::x11_apply_settings();
00771
00772
00773
00774
00775 paletteAlreadySet = (QApplicationPrivate::sys_pal != 0);
00776
00777
00778 int format;
00779 ulong nitems, after = 1;
00780 QString res;
00781 long offset = 0;
00782 Atom type = XNone;
00783
00784 while (after > 0) {
00785 uchar *data = 0;
00786 XGetWindowProperty(X11->display, QX11Info::appRootWindow(0),
00787 ATOM(RESOURCE_MANAGER),
00788 offset, 8192, False, AnyPropertyType,
00789 &type, &format, &nitems, &after,
00790 &data);
00791 if (type == XA_STRING)
00792 res += QString::fromLatin1((char*)data);
00793 else
00794 res += QString::fromLocal8Bit((char*)data);
00795 offset += 2048;
00796 if (data)
00797 XFree((char *)data);
00798 }
00799
00800 QString key, value;
00801 int l = 0, r;
00802 QString apn = QString::fromLocal8Bit(appName);
00803 QString apc = QString::fromLocal8Bit(appClass);
00804 int apnl = apn.length();
00805 int apcl = apc.length();
00806 int resl = res.length();
00807
00808 while (l < resl) {
00809 r = res.indexOf(QLatin1Char('\n'), l);
00810 if (r < 0)
00811 r = resl;
00812 while (QUnicodeTables::isSpace(res.at(l)))
00813 l++;
00814 bool mine = false;
00815 QChar sc = res.at(l + 1);
00816 if (res.at(l) == QLatin1Char('*') &&
00817 (sc == QLatin1Char('f') || sc == QLatin1Char('b') || sc == QLatin1Char('g') ||
00818 sc == QLatin1Char('F') || sc == QLatin1Char('B') || sc == QLatin1Char('G') ||
00819 sc == QLatin1Char('s') || sc == QLatin1Char('S')
00820
00821 || sc == QLatin1Char('T'))) {
00822
00823 QString item = res.mid(l, r - l).simplified();
00824 int i = item.indexOf(QLatin1Char(':'));
00825 key = item.left(i).trimmed().mid(1).toLower();
00826 value = item.right(item.length() - i - 1).trimmed();
00827 mine = true;
00828 } else if (apnl && res.at(l) == apn.at(0) || (appClass && apcl && res.at(l) == apc.at(0))) {
00829 if (res.mid(l,apnl) == apn && (res.at(l+apnl) == QLatin1Char('.')
00830 || res.at(l+apnl) == QLatin1Char('*'))) {
00831 QString item = res.mid(l, r - l).simplified();
00832 int i = item.indexOf(QLatin1Char(':'));
00833 key = item.left(i).trimmed().mid(apnl+1).toLower();
00834 value = item.right(item.length() - i - 1).trimmed();
00835 mine = true;
00836 } else if (res.mid(l,apcl) == apc && (res.at(l+apcl) == QLatin1Char('.')
00837 || res.at(l+apcl) == QLatin1Char('*'))) {
00838 QString item = res.mid(l, r - l).simplified();
00839 int i = item.indexOf(QLatin1Char(':'));
00840 key = item.left(i).trimmed().mid(apcl+1).toLower();
00841 value = item.right(item.length() - i - 1).trimmed();
00842 mine = true;
00843 }
00844 }
00845
00846 if (mine) {
00847 if (!font && key == QLatin1String("systemfont"))
00848 sysFont = value.left(value.lastIndexOf(QLatin1Char(':')));
00849 if (!font && key == QLatin1String("font"))
00850 resFont = value;
00851 else if (!fg && !paletteAlreadySet) {
00852 if (key == QLatin1String("foreground"))
00853 resFG = value;
00854 else if (!bg && key == QLatin1String("background"))
00855 resBG = value;
00856 else if (key == QLatin1String("text.selectbackground")) {
00857 selectBackground = value;
00858 } else if (key == QLatin1String("text.selectforeground")) {
00859 selectForeground = value;
00860 }
00861 } else if (key == QLatin1String("guieffects"))
00862 resEF = value;
00863
00864 }
00865
00866 l = r + 1;
00867 }
00868 }
00869 if (!sysFont.isEmpty())
00870 resFont = sysFont;
00871 if (resFont.isEmpty())
00872 resFont = QString::fromLocal8Bit(font);
00873 if (resFG.isEmpty())
00874 resFG = QString::fromLocal8Bit(fg);
00875 if (resBG.isEmpty())
00876 resBG = QString::fromLocal8Bit(bg);
00877 if (!qt_app_has_font && !resFont.isEmpty()) {
00878 QFont fnt;
00879 fnt.setRawName(resFont);
00880
00881
00882
00883 if (! fnt.exactMatch()) {
00884 QFontInfo fontinfo(fnt);
00885 fnt.setFamily(fontinfo.family());
00886 fnt.setRawMode(fontinfo.rawMode());
00887
00888 if (! fnt.rawMode()) {
00889 fnt.setItalic(fontinfo.italic());
00890 fnt.setWeight(fontinfo.weight());
00891 fnt.setUnderline(fontinfo.underline());
00892 fnt.setStrikeOut(fontinfo.strikeOut());
00893 fnt.setStyleHint(fontinfo.styleHint());
00894
00895 if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
00896
00897 qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
00898 if (pointSize <= 0)
00899 pointSize = 12;
00900 fnt.setPointSize(qRound(pointSize));
00901 }
00902 }
00903 }
00904
00905 if (fnt != QApplication::font()) {
00906 QApplication::setFont(fnt);
00907 }
00908 }
00909
00910 if ((button || !resBG.isEmpty() || !resFG.isEmpty())) {
00911 (void) QApplication::style();
00912 QColor btn;
00913 QColor bg;
00914 QColor fg;
00915 if (!resBG.isEmpty())
00916 bg = QColor(resBG);
00917 if (!bg.isValid())
00918 bg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Window);
00919
00920 if (!resFG.isEmpty())
00921 fg = QColor(resFG);
00922 if (!fg.isValid())
00923 fg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::WindowText);
00924
00925 if (button)
00926 btn = QColor(QString::fromLocal8Bit(button));
00927 else if (!resBG.isEmpty())
00928 btn = bg;
00929 if (!btn.isValid())
00930 btn = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Button);
00931
00932 int h,s,v;
00933 fg.getHsv(&h,&s,&v);
00934 QColor base = Qt::white;
00935 bool bright_mode = false;
00936 if (v >= 255-50) {
00937 base = btn.dark(150);
00938 bright_mode = true;
00939 }
00940
00941 QPalette pal(fg, btn, btn.light(), btn.dark(), btn.dark(150), fg, Qt::white, base, bg);
00942 QColor disabled((fg.red() + btn.red()) / 2,
00943 (fg.green() + btn.green())/ 2,
00944 (fg.blue() + btn.blue()) / 2);
00945 pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.light(125),
00946 btn.dark(), btn.dark(150), disabled, Qt::white, Qt::white, bg);
00947
00948 QColor highlight, highlightText;
00949 if (!selectBackground.isEmpty() && !selectForeground.isEmpty()) {
00950 highlight = QColor(selectBackground);
00951 highlightText = QColor(selectForeground);
00952 }
00953
00954 if (highlight.isValid() && highlightText.isValid()) {
00955 pal.setColor(QPalette::Highlight, highlight);
00956 pal.setColor(QPalette::HighlightedText, highlightText);
00957
00958
00959 highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
00960 highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
00961 pal.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
00962 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
00963 } else if (bright_mode) {
00964 pal.setColor(QPalette::HighlightedText, base);
00965 pal.setColor(QPalette::Highlight, Qt::white);
00966 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
00967 pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
00968 } else {
00969 pal.setColor(QPalette::HighlightedText, Qt::white);
00970 pal.setColor(QPalette::Highlight, Qt::darkBlue);
00971 pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
00972 pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
00973 }
00974
00975 QApplicationPrivate::setSystemPalette(pal);
00976 }
00977
00978 if (!resEF.isEmpty()) {
00979 QStringList effects = resEF.split(QLatin1Char(' '));
00980 QApplication::setEffectEnabled(Qt::UI_General, effects.contains(QLatin1String("general")));
00981 QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
00982 effects.contains(QLatin1String("animatemenu")));
00983 QApplication::setEffectEnabled(Qt::UI_FadeMenu,
00984 effects.contains(QLatin1String("fademenu")));
00985 QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
00986 effects.contains(QLatin1String("animatecombo")));
00987 QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
00988 effects.contains(QLatin1String("animatetooltip")));
00989 QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
00990 effects.contains(QLatin1String("fadetooltip")));
00991 QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
00992 effects.contains(QLatin1String("animatetoolbox")));
00993 }
00994 }
00995
00996
00997 static void qt_detect_broken_window_manager()
00998 {
00999 Atom type;
01000 int format;
01001 ulong nitems, after;
01002 uchar *data = 0;
01003
01004
01005 int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
01006 ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW,
01007 &type, &format, &nitems, &after, &data);
01008 if (data)
01009 XFree(data);
01010
01011 if (e == Success && type == XA_WINDOW && format == 32 && nitems == 1 && after == 0) {
01012
01013 qt_broken_wm = true;
01014 }
01015 }
01016
01017
01018
01019 static void qt_get_net_supported()
01020 {
01021 Atom type;
01022 int format;
01023 long offset = 0;
01024 unsigned long nitems, after;
01025 unsigned char *data = 0;
01026
01027 int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
01028 ATOM(_NET_SUPPORTED), 0, 0,
01029 False, XA_ATOM, &type, &format, &nitems, &after, &data);
01030 if (data)
01031 XFree(data);
01032
01033 if (X11->net_supported_list)
01034 delete [] X11->net_supported_list;
01035 X11->net_supported_list = 0;
01036
01037 if (e == Success && type == XA_ATOM && format == 32) {
01038 QBuffer ts;
01039 ts.open(QIODevice::WriteOnly);
01040
01041 while (after > 0) {
01042 XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
01043 ATOM(_NET_SUPPORTED), offset, 1024,
01044 False, XA_ATOM, &type, &format, &nitems, &after, &data);
01045
01046 if (type == XA_ATOM && format == 32) {
01047 ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
01048 offset += nitems;
01049 } else
01050 after = 0;
01051 if (data)
01052 XFree(data);
01053 }
01054
01055
01056 QByteArray buffer(ts.buffer());
01057 nitems = buffer.size() / sizeof(Atom);
01058 X11->net_supported_list = new Atom[nitems + 1];
01059 Atom *a = (Atom *) buffer.data();
01060 uint i;
01061 for (i = 0; i < nitems; i++)
01062 X11->net_supported_list[i] = a[i];
01063 X11->net_supported_list[nitems] = 0;
01064 }
01065 }
01066
01067
01068 bool qt_net_supports(Atom atom)
01069 {
01070 if (! X11->net_supported_list)
01071 return false;
01072
01073 bool supported = false;
01074 int i = 0;
01075 while (X11->net_supported_list[i] != 0) {
01076 if (X11->net_supported_list[i++] == atom) {
01077 supported = true;
01078 break;
01079 }
01080 }
01081
01082 return supported;
01083 }
01084
01085
01086
01087 static void qt_get_net_virtual_roots()
01088 {
01089 if (X11->net_virtual_root_list)
01090 delete [] X11->net_virtual_root_list;
01091 X11->net_virtual_root_list = 0;
01092
01093 if (!qt_net_supports(ATOM(_NET_VIRTUAL_ROOTS)))
01094 return;
01095
01096 Atom type;
01097 int format;
01098 long offset = 0;
01099 unsigned long nitems, after;
01100 unsigned char *data;
01101
01102 int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
01103 ATOM(_NET_VIRTUAL_ROOTS), 0, 0,
01104 False, XA_ATOM, &type, &format, &nitems, &after, &data);
01105 if (data)
01106 XFree(data);
01107
01108 if (e == Success && type == XA_ATOM && format == 32) {
01109 QBuffer ts;
01110 ts.open(QIODevice::WriteOnly);
01111
01112 while (after > 0) {
01113 XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
01114 ATOM(_NET_VIRTUAL_ROOTS), offset, 1024,
01115 False, XA_ATOM, &type, &format, &nitems, &after, &data);
01116
01117 if (type == XA_ATOM && format == 32) {
01118 ts.write(reinterpret_cast<char *>(data), nitems * 4);
01119 offset += nitems;
01120 } else
01121 after = 0;
01122 if (data)
01123 XFree(data);
01124 }
01125
01126
01127 QByteArray buffer(ts.buffer());
01128 nitems = buffer.size() / sizeof(Window);
01129 X11->net_virtual_root_list = new Window[nitems + 1];
01130 Window *a = (Window *) buffer.data();
01131 uint i;
01132 for (i = 0; i < nitems; i++)
01133 X11->net_virtual_root_list[i] = a[i];
01134 X11->net_virtual_root_list[nitems] = 0;
01135 }
01136 }
01137
01138 static void qt_net_update_user_time(QWidget *tlw)
01139 {
01140 Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
01141 XChangeProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME),
01142 XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &X11->userTime, 1);
01143 }
01144
01145 static void qt_check_focus_model()
01146 {
01147 Window fw = XNone;
01148 int unused;
01149 XGetInputFocus(X11->display, &fw, &unused);
01150 if (fw == PointerRoot)
01151 X11->focus_model = QX11Data::FM_PointerRoot;
01152 else
01153 X11->focus_model = QX11Data::FM_Other;
01154 }
01155
01156 #ifndef QT_NO_TABLET
01157 static bool isXInputSupported(Display *dpy)
01158 {
01159 Bool exists;
01160 XExtensionVersion *version;
01161 exists = XQueryExtension(dpy, "XInputExtension", &X11->xinput_major,
01162 &X11->xinput_eventbase, &X11->xinput_errorbase);
01163 if (!exists)
01164 return false;
01165 version = XGetExtensionVersion(dpy, "XInputExtension");
01166 if (!version || version == reinterpret_cast<XExtensionVersion *>(NoSuchExtension))
01167 return false;
01168
01169 XFree(version);
01170 return true;
01171 }
01172 #endif
01173
01174
01175
01176
01177
01178 #if !defined(QT_NO_FONTCONFIG)
01179 static void getXDefault(const char *group, const char *key, int *val)
01180 {
01181 char *str = XGetDefault(X11->display, group, key);
01182 if (str) {
01183 char *end = 0;
01184 int v = strtol(str, &end, 0);
01185 if (str != end)
01186 *val = v;
01187 }
01188 }
01189
01190 static void getXDefault(const char *group, const char *key, double *val)
01191 {
01192 char *str = XGetDefault(X11->display, group, key);
01193 if (str) {
01194 char *end = 0;
01195 double v = strtod(str, &end);
01196 if (str != end)
01197 *val = v;
01198 }
01199 }
01200
01201 static void getXDefault(const char *group, const char *key, bool *val)
01202 {
01203 char *str = XGetDefault(X11->display, group, key);
01204 if (str) {
01205 char c = str[0];
01206 if (isupper((int)c))
01207 c = tolower(c);
01208 if (c == 't' || c == 'y' || c == '1')
01209 *val = true;
01210 else if (c == 'f' || c == 'n' || c == '0')
01211 *val = false;
01212 if (c == 'o') {
01213 c = str[1];
01214 if (isupper((int)c))
01215 c = tolower(c);
01216 if (c == 'n')
01217 *val = true;
01218 if (c == 'f')
01219 *val = false;
01220 }
01221 }
01222 }
01223 #endif
01224
01225
01226
01227
01228
01229 void qt_init(QApplicationPrivate *priv, int,
01230 Display *display, Qt::HANDLE visual, Qt::HANDLE colormap)
01231 {
01232 X11 = new QX11Data;
01233 X11->display = display;
01234 X11->displayName = 0;
01235 X11->foreignDisplay = (display != 0);
01236 X11->focus_model = -1;
01237
01238
01239 X11->use_xrandr = false;
01240 X11->xrandr_major = 0;
01241 X11->xrandr_eventbase = 0;
01242 X11->xrandr_errorbase = 0;
01243
01244
01245 X11->use_xrender = false;
01246 X11->xrender_major = 0;
01247 X11->xrender_version = 0;
01248
01249
01250 X11->use_xfixes = false;
01251 X11->xfixes_major = 0;
01252 X11->xfixes_eventbase = 0;
01253 X11->xfixes_errorbase = 0;
01254
01255
01256 X11->use_xinput = false;
01257 X11->xinput_major = 0;
01258 X11->xinput_eventbase = 0;
01259 X11->xinput_errorbase = 0;
01260
01261 X11->sip_serial = 0;
01262 X11->net_supported_list = 0;
01263 X11->net_virtual_root_list = 0;
01264 X11->wm_client_leader = 0;
01265 X11->screens = 0;
01266 X11->screenCount = 0;
01267 X11->time = CurrentTime;
01268 X11->userTime = CurrentTime;
01269 X11->ignore_badwindow = false;
01270 X11->seen_badwindow = false;
01271
01272 X11->motifdnd_active = false;
01273
01274 X11->default_im = QLatin1String("imsw-multi");
01275 priv->inputContext = 0;
01276
01277
01278 X11->visual_class = -1;
01279 X11->visual_id = -1;
01280 X11->color_count = 0;
01281 X11->custom_cmap = false;
01282
01283
01284 X11->visual = reinterpret_cast<Visual *>(visual);
01285 X11->colormap = colormap;
01286
01287 #ifndef QT_NO_XRENDER
01288 memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
01289 for (int i = 0; i < X11->solid_fill_count; ++i)
01290 X11->solid_fills[i].screen = -1;
01291 memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
01292 for (int i = 0; i < X11->pattern_fill_count; ++i)
01293 X11->pattern_fills[i].screen = -1;
01294 #endif
01295
01296 X11->startupId = 0;
01297
01298 int argc = priv->argc;
01299 char **argv = priv->argv;
01300
01301 if (X11->display) {
01302
01303
01304
01305 appName = qstrdup("Qt-subapplication");
01306 char *app_class = 0;
01307 if (argv) {
01308 const char* p = strrchr(argv[0], '/');
01309 app_class = qstrdup(p ? p + 1 : argv[0]);
01310 if (app_class[0])
01311 app_class[0] = toupper(app_class[0]);
01312 }
01313 appClass = app_class;
01314 } else {
01315
01316
01317
01318 char *app_class = 0;
01319 if (argv && argv[0]) {
01320 const char *p = strrchr(argv[0], '/');
01321 appName = p ? p + 1 : argv[0];
01322 app_class = qstrdup(appName);
01323 if (app_class[0])
01324 app_class[0] = toupper(app_class[0]);
01325 }
01326 appClass = app_class;
01327 }
01328
01329
01330 original_x_errhandler = XSetErrorHandler(qt_x_errhandler);
01331 original_xio_errhandler = XSetIOErrorHandler(qt_xio_errhandler);
01332
01333
01334 int j = argc ? 1 : 0;
01335 for (int i=1; i<argc; i++) {
01336 if (argv[i] && *argv[i] != '-') {
01337 argv[j++] = argv[i];
01338 continue;
01339 }
01340 QByteArray arg(argv[i]);
01341 if (arg == "-display") {
01342 if (++i < argc && !X11->display)
01343 X11->displayName = argv[i];
01344 } else if (arg == "-fn" || arg == "-font") {
01345 if (++i < argc)
01346 appFont = argv[i];
01347 } else if (arg == "-bg" || arg == "-background") {
01348 if (++i < argc)
01349 appBGCol = argv[i];
01350 } else if (arg == "-btn" || arg == "-button") {
01351 if (++i < argc)
01352 appBTNCol = argv[i];
01353 } else if (arg == "-fg" || arg == "-foreground") {
01354 if (++i < argc)
01355 appFGCol = argv[i];
01356 } else if (arg == "-name") {
01357 if (++i < argc)
01358 appName = argv[i];
01359 } else if (arg == "-title") {
01360 if (++i < argc)
01361 mwTitle = argv[i];
01362 } else if (arg == "-geometry") {
01363 if (++i < argc)
01364 mwGeometry = argv[i];
01365 } else if (arg == "-im") {
01366 if (++i < argc)
01367 qt_ximServer = argv[i];
01368 #if 0
01369 } else if (arg == "-noxim") {
01370 noxim=true;
01371 #endif
01372 } else if (arg == "-ncols") {
01373 if (++i < argc)
01374 X11->color_count = qMax(0,atoi(argv[i]));
01375 } else if (arg == "-visual") {
01376 if (++i < argc && !X11->visual) {
01377 QString s = QString::fromLocal8Bit(argv[i]).toLower();
01378 if (s == QLatin1String("staticgray"))
01379 X11->visual_class = StaticGray;
01380 else if (s == QLatin1String("grayscale"))
01381 X11->visual_class = XGrayScale;
01382 else if (s == QLatin1String("staticcolor"))
01383 X11->visual_class = StaticColor;
01384 else if (s == QLatin1String("pseudocolor"))
01385 X11->visual_class = PseudoColor;
01386 else if (s == QLatin1String("truecolor"))
01387 X11->visual_class = TrueColor;
01388 else if (s == QLatin1String("directcolor"))
01389 X11->visual_class = DirectColor;
01390 else
01391 X11->visual_id = static_cast<int>(strtol(argv[i], 0, 0));
01392 }
01393 #ifndef QT_NO_XIM
01394 } else if (arg == "-inputstyle") {
01395 if (++i < argc) {
01396 QString s = QString::fromLocal8Bit(argv[i]).toLower();
01397 if (s == QLatin1String("onthespot"))
01398 qt_xim_preferred_style = XIMPreeditCallbacks |
01399 XIMStatusNothing;
01400 else if (s == QLatin1String("overthespot"))
01401 qt_xim_preferred_style = XIMPreeditPosition |
01402 XIMStatusNothing;
01403 else if (s == QLatin1String("offthespot"))
01404 qt_xim_preferred_style = XIMPreeditArea |
01405 XIMStatusArea;
01406 else if (s == QLatin1String("root"))
01407 qt_xim_preferred_style = XIMPreeditNothing |
01408 XIMStatusNothing;
01409 }
01410 #endif
01411 } else if (arg == "-cmap") {
01412 if (!X11->colormap)
01413 X11->custom_cmap = true;
01414 }
01415 #if defined(QT_DEBUG)
01416 else if (arg == "-sync")
01417 appSync = !appSync;
01418 else if (arg == "-nograb")
01419 appNoGrab = !appNoGrab;
01420 else if (arg == "-dograb")
01421 appDoGrab = !appDoGrab;
01422 #endif
01423 else
01424 argv[j++] = argv[i];
01425 }
01426
01427 priv->argc = j;
01428
01429 #if defined(QT_DEBUG) && defined(Q_OS_LINUX)
01430 if (!appNoGrab && !appDoGrab) {
01431 QString s;
01432 s.sprintf("/proc/%d/cmdline", getppid());
01433 QFile f(s);
01434 if (f.open(QIODevice::ReadOnly)) {
01435 s.clear();
01436 char c;
01437 while (f.getChar(&c) && c) {
01438 if (c == '/')
01439 s.clear();
01440 else
01441 s += QLatin1Char(c);
01442 }
01443 if (s == QLatin1String("gdb")) {
01444 appNoGrab = true;
01445 qDebug("Qt: gdb: -nograb added to command-line options.\n"
01446 "\t Use the -dograb option to enforce grabbing.");
01447 }
01448 f.close();
01449 }
01450 }
01451 #endif
01452
01453
01454 if (qt_is_gui_used && !X11->display) {
01455 if ((X11->display = XOpenDisplay(X11->displayName)) == 0) {
01456 qWarning("%s: cannot connect to X server %s", appName,
01457 XDisplayName(X11->displayName));
01458 QApplicationPrivate::reset_instance_pointer();
01459 exit(1);
01460 }
01461
01462 if (appSync)
01463 XSynchronize(X11->display, true);
01464 }
01465
01466
01467
01468
01469
01470 if (qt_is_gui_used) {
01471 X11->defaultScreen = DefaultScreen(X11->display);
01472 X11->screenCount = ScreenCount(X11->display);
01473
01474 X11->screens = new QX11InfoData[X11->screenCount];
01475
01476 for (int s = 0; s < X11->screenCount; s++) {
01477 QX11InfoData *screen = X11->screens + s;
01478 screen->ref = 1;
01479 screen->screen = s;
01480 screen->dpiX = (DisplayWidth(X11->display, s) * 254 + DisplayWidthMM(X11->display, s)*5)
01481 / (DisplayWidthMM(X11->display, s)*10);
01482 screen->dpiY = (DisplayHeight(X11->display, s) * 254 + DisplayHeightMM(X11->display, s)*5)
01483 / (DisplayHeightMM(X11->display, s)*10);
01484 }
01485
01486 QColormap::initialize();
01487
01488
01489 X11->xdndSetup();
01490
01491
01492 qt_x11_create_intern_atoms();
01493
01494
01495 qt_detect_broken_window_manager();
01496
01497
01498 qt_get_net_supported();
01499 qt_get_net_virtual_roots();
01500
01501 #ifndef QT_NO_XRANDR
01502
01503 if (XQueryExtension(X11->display, "RANDR", &X11->xrandr_major,
01504 &X11->xrandr_eventbase, &X11->xrandr_errorbase)
01505 && XRRQueryExtension(X11->display, &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
01506
01507 X11->use_xrandr = true;
01508 }
01509 #endif // QT_NO_XRANDR
01510
01511 #ifndef QT_NO_XRENDER
01512 int xrender_eventbase, xrender_errorbase;
01513
01514 if (XQueryExtension(X11->display, "RENDER", &X11->xrender_major,
01515 &xrender_eventbase, &xrender_errorbase)
01516 && XRenderQueryExtension(X11->display, &xrender_eventbase,
01517 &xrender_errorbase)) {
01518
01519
01520 XRenderPictFormat *format =
01521 XRenderFindVisualFormat(X11->display,
01522 (Visual *) QX11Info::appVisual(X11->defaultScreen));
01523
01524 int major = 0;
01525 int minor = 0;
01526 XRenderQueryVersion(X11->display, &major, &minor);
01527 if (qgetenv("QT_X11_NO_XRENDER").isNull() && format != 0) {
01528 X11->use_xrender = (major >= 0 && minor >= 5);
01529 X11->xrender_version = major*100+minor;
01530
01531
01532 if (X11->xrender_version == 10
01533 && VendorRelease(X11->display) < 60900000
01534 && QByteArray(ServerVendor(X11->display)).contains("X.Org"))
01535 X11->xrender_version = 9;
01536 }
01537 }
01538 #endif // QT_NO_XRENDER
01539
01540 #ifndef QT_NO_XFIXES
01541
01542 if (XQueryExtension(X11->display, "XFIXES", &X11->xfixes_major,
01543 &X11->xfixes_eventbase, &X11->xfixes_errorbase)
01544 && XFixesQueryExtension(X11->display, &X11->xfixes_eventbase,
01545 &X11->xfixes_errorbase)) {
01546
01547
01548
01549
01550
01551
01552
01553 int major = 3;
01554 int minor = 0;
01555 XFixesQueryVersion(X11->display, &major, &minor);
01556 X11->use_xfixes = (major >= 2);
01557 X11->xfixes_major = major;
01558 }
01559 #endif // QT_NO_XFIXES
01560
01561 X11->has_fontconfig = false;
01562 #if !defined(QT_NO_FONTCONFIG)
01563 if (qgetenv("QT_X11_NO_FONTCONFIG").isNull())
01564 X11->has_fontconfig = FcInit();
01565
01566 int dpi = 0;
01567 getXDefault("Xft", FC_DPI, &dpi);
01568 if (dpi) {
01569 for (int s = 0; s < ScreenCount(X11->display); ++s) {
01570 QX11Info::setAppDpiX(s, dpi);
01571 QX11Info::setAppDpiY(s, dpi);
01572 }
01573 }
01574 X11->fc_scale = 1.;
01575 getXDefault("Xft", FC_SCALE, &X11->fc_scale);
01576 for (int s = 0; s < ScreenCount(X11->display); ++s) {
01577 int subpixel = FC_RGBA_UNKNOWN;
01578 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
01579 if (X11->use_xrender) {
01580 int rsp = XRenderQuerySubpixelOrder(X11->display, s);
01581 switch (rsp) {
01582 default:
01583 case SubPixelUnknown:
01584 subpixel = FC_RGBA_UNKNOWN;
01585 break;
01586 case SubPixelHorizontalRGB:
01587 subpixel = FC_RGBA_RGB;
01588 break;
01589 case SubPixelHorizontalBGR:
01590 subpixel = FC_RGBA_BGR;
01591 break;
01592 case SubPixelVerticalRGB:
01593 subpixel = FC_RGBA_VRGB;
01594 break;
01595 case SubPixelVerticalBGR:
01596 subpixel = FC_RGBA_VBGR;
01597 break;
01598 case SubPixelNone:
01599 subpixel = FC_RGBA_NONE;
01600 break;
01601 }
01602 }
01603 #endif
01604 getXDefault("Xft", FC_RGBA, &subpixel);
01605 X11->screens[s].subpixel = subpixel;
01606 }
01607 X11->fc_antialias = true;
01608 getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
01609 #ifdef FC_HINT_STYLE
01610 getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
01611 #endif
01612 #if 0
01613
01614 getXDefault("Xft", FC_AUTOHINT, &X11->fc_autohint);
01615 getXDefault("Xft", FC_HINTING, &X11->fc_autohint);
01616 getXDefault("Xft", FC_MINSPACE, &X11->fc_autohint);
01617 #endif
01618 #endif // QT_NO_XRENDER
01619
01620
01621 QKeyMapper::changeKeyboard();
01622
01623 #ifndef QT_NO_XKB
01624 if (qt_keymapper_private()->useXKB) {
01625
01626
01627 unsigned int state = XkbPCF_GrabsUseXKBStateMask;
01628 (void) XkbSetPerClientControls(X11->display, state, &state);
01629 }
01630 #endif // QT_NO_XKB
01631
01632
01633 #if 0 //disabled for now..
01634 QSegfaultHandler::initialize(priv->argv, priv->argc);
01635 #endif
01636 QFont::initialize();
01637 QCursorData::initialize();
01638 }
01639
01640 if(qt_is_gui_used) {
01641 qApp->setObjectName(QString::fromLocal8Bit(appName));
01642
01643 int screen;
01644 for (screen = 0; screen < X11->screenCount; ++screen) {
01645 XSelectInput(X11->display, QX11Info::appRootWindow(screen),
01646 KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask);
01647
01648 #ifndef QT_NO_XRANDR
01649 if (X11->use_xrandr)
01650 XRRSelectInput(X11->display, QX11Info::appRootWindow(screen), True);
01651 #endif
01652 }
01653 }
01654
01655 if (qt_is_gui_used) {
01656
01657
01658
01659 X11->desktopEnvironment = DE_UNKNOWN;
01660
01661
01662 Window windowManagerWindow = XNone;
01663 Atom typeReturned;
01664 int formatReturned;
01665 unsigned long nitemsReturned;
01666 unsigned long unused;
01667 unsigned char *data = 0;
01668 if (XGetWindowProperty(QX11Info::display(), QX11Info::appRootWindow(),
01669 ATOM(_NET_SUPPORTING_WM_CHECK),
01670 0, 1024, False, XA_WINDOW, &typeReturned,
01671 &formatReturned, &nitemsReturned, &unused, &data)
01672 == Success) {
01673 if (typeReturned == XA_WINDOW && formatReturned == 32)
01674 windowManagerWindow = *((Window*) data);
01675 if (data)
01676 XFree(data);
01677
01678 if (windowManagerWindow != XNone) {
01679 QString wmName;
01680 Atom utf8atom = ATOM(UTF8_STRING);
01681 if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
01682 0, 1024, False, utf8atom, &typeReturned,
01683 &formatReturned, &nitemsReturned, &unused, &data)
01684 == Success) {
01685 if (typeReturned == utf8atom && formatReturned == 8)
01686 wmName = QString::fromUtf8((const char*)data);
01687 if (data)
01688 XFree(data);
01689 if (wmName == QLatin1String("KWin"))
01690 X11->desktopEnvironment = DE_KDE;
01691 if (wmName == QLatin1String("Metacity"))
01692 X11->desktopEnvironment = DE_GNOME;
01693 }
01694 }
01695 }
01696
01697
01698 if (X11->desktopEnvironment == DE_UNKNOWN){
01699 Atom type;
01700 int format;
01701 unsigned long length, after;
01702 uchar *data = 0;
01703
01704 if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
01705 0, 1, False, AnyPropertyType, &type, &format, &length,
01706 &after, &data) == Success && length) {
01707
01708 X11->desktopEnvironment = DE_CDE;
01709 } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
01710 ATOM(GNOME_BACKGROUND_PROPERTIES), 0, 1, False, AnyPropertyType,
01711 &type, &format, &length, &after, &data) == Success && length) {
01712 X11->desktopEnvironment = DE_GNOME;
01713 } else if ((XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KDE_FULL_SESSION),
01714 0, 1, False, AnyPropertyType, &type, &format, &length, &after, &data) == Success
01715 && length)
01716 || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWIN_RUNNING),
01717 0, 1, False, AnyPropertyType, &type, &format, &length,
01718 &after, &data) == Success
01719 && length)
01720 || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWM_RUNNING),
01721 0, 1, False, AnyPropertyType, &type, &format, &length,
01722 &after, &data) == Success && length)) {
01723 X11->desktopEnvironment = DE_KDE;
01724 }
01725 if (data)
01726 XFree((char *)data);
01727 }
01728
01729 qt_set_input_encoding();
01730
01731 qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol);
01732
01733
01734
01735
01736
01737
01738 int ptsz = (X11->use_xrender
01739 ? 9
01740 : (int) (((QX11Info::appDpiY() >= 95 ? 17. : 12.) *
01741 72. / (float) QX11Info::appDpiY()) + 0.5));
01742
01743 if (!qt_app_has_font) {
01744 QFont f(X11->has_fontconfig ? QLatin1String("Sans Serif") : QLatin1String("Helvetica"),
01745 ptsz);
01746 QApplication::setFont(f);
01747 }
01748
01749 #if !defined (QT_NO_TABLET)
01750 if (isXInputSupported(X11->display)) {
01751 int ndev,
01752 i,
01753 j;
01754 bool gotStylus,
01755 gotEraser;
01756 XDeviceInfo *devices, *devs;
01757 XInputClassInfo *ip;
01758 XAnyClassPtr any;
01759 XValuatorInfoPtr v;
01760 XAxisInfoPtr a;
01761 XDevice *dev;
01762
01763 #if !defined(Q_OS_IRIX)
01764
01765 const QString XFREENAMESTYLUS = QLatin1String("stylus");
01766 const QString XFREENAMEPEN = QLatin1String("pen");
01767 const QString XFREENAMEERASER = QLatin1String("eraser");
01768 #endif
01769
01770 devices = XListInputDevices(X11->display, &ndev);
01771 if (!devices) {
01772 qWarning("QApplication: Failed to get list of devices");
01773 ndev = -1;
01774 }
01775 QTabletEvent::TabletDevice deviceType;
01776 dev = 0;
01777 for (devs = devices, i = 0; i < ndev; i++, devs++) {
01778 gotStylus = false;
01779 gotEraser = false;
01780
01781 QString devName = QString::fromLocal8Bit(devs->name).toLower();
01782 #if defined(Q_OS_IRIX)
01783 if (devName == QLatin1String(WACOM_NAME)) {
01784 deviceType = QTabletEvent::Stylus;
01785 gotStylus = true;
01786 }
01787 #else
01788 if (devName.startsWith(XFREENAMEPEN)
01789 || devName.startsWith(XFREENAMESTYLUS)) {
01790 deviceType = QTabletEvent::Stylus;
01791 gotStylus = true;
01792 } else if (devName.startsWith(XFREENAMEERASER)) {
01793 deviceType = QTabletEvent::XFreeEraser;
01794 gotEraser = true;
01795 }
01796 #endif
01797
01798 if (gotStylus || gotEraser) {
01799 dev = XOpenDevice(X11->display, devs->id);
01800
01801 if (!dev)
01802 continue;
01803
01804 QTabletDeviceData device_data;
01805 device_data.deviceType = deviceType;
01806 device_data.eventCount = 0;
01807 device_data.device = dev;
01808 device_data.xinput_motion = -1;
01809 device_data.xinput_key_press = -1;
01810 device_data.xinput_key_release = -1;
01811 device_data.xinput_button_press = -1;
01812 device_data.xinput_button_release = -1;
01813 device_data.xinput_proximity_in = -1;
01814 device_data.xinput_proximity_out = -1;
01815
01816 if (dev->num_classes > 0) {
01817 for (ip = dev->classes, j = 0; j < devs->num_classes;
01818 ip++, j++) {
01819 switch (ip->input_class) {
01820 case KeyClass:
01821 DeviceKeyPress(dev, device_data.xinput_key_press,
01822 device_data.eventList[device_data.eventCount]);
01823 if (device_data.eventList[device_data.eventCount])
01824 ++device_data.eventCount;
01825 DeviceKeyRelease(dev, device_data.xinput_key_release,
01826 device_data.eventList[device_data.eventCount]);
01827 if (device_data.eventList[device_data.eventCount])
01828 ++device_data.eventCount;
01829 break;
01830 case ButtonClass:
01831 DeviceButtonPress(dev, device_data.xinput_button_press,
01832 device_data.eventList[device_data.eventCount]);
01833 if (device_data.eventList[device_data.eventCount])
01834 ++device_data.eventCount;
01835 DeviceButtonRelease(dev, device_data.xinput_button_release,
01836 device_data.eventList[device_data.eventCount]);
01837 if (device_data.eventList[device_data.eventCount])
01838 ++device_data.eventCount;
01839 break;
01840 case ValuatorClass:
01841
01842
01843 DeviceMotionNotify(dev, device_data.xinput_motion,
01844 device_data.eventList[device_data.eventCount]);
01845 if (device_data.eventList[device_data.eventCount])
01846 ++device_data.eventCount;
01847 ProximityIn(dev, device_data.xinput_proximity_in, device_data.eventList[device_data.eventCount]);
01848 if (device_data.eventList[device_data.eventCount])
01849 ++device_data.eventCount;
01850 ProximityOut(dev, device_data.xinput_proximity_out, device_data.eventList[device_data.eventCount]);
01851 if (device_data.eventList[device_data.eventCount])
01852 ++device_data.eventCount;
01853 default:
01854 break;
01855 }
01856 }
01857 }
01858
01859
01860 any = (XAnyClassPtr) (devs->inputclassinfo);
01861 for (j = 0; j < devs->num_classes; j++) {
01862 if (any->c_class == ValuatorClass) {
01863 v = (XValuatorInfoPtr) any;
01864 a = (XAxisInfoPtr) ((char *) v +
01865 sizeof (XValuatorInfo));
01866 #if defined (Q_OS_IRIX)
01867
01868
01869
01870
01871
01872
01873 char returnString[SGIDeviceRtrnLen];
01874 int tmp;
01875 if (XSGIMiscQueryExtension(X11->display, &tmp, &tmp)
01876 && XSGIDeviceQuery(X11->display, devs->id,
01877 "dimensions", returnString)) {
01878 QString str = QLatin1String(returnString);
01879 int comma = str.indexOf(',');
01880 device_data.minX = 0;
01881 device_data.minY = 0;
01882 device_data.maxX = str.left(comma).toInt();
01883 device_data.maxY = str.mid(comma + 1).toInt();
01884 } else {
01885 device_data.minX = a[WAC_XCOORD_I].min_value;
01886 device_data.maxX = a[WAC_XCOORD_I].max_value;
01887 device_data.minY = a[WAC_YCOORD_I].min_value;
01888 device_data.maxY = a[WAC_YCOORD_I].max_value;
01889 }
01890 device_data.minPressure = a[WAC_PRESSURE_I].min_value;
01891 device_data.maxPressure = a[WAC_PRESSURE_I].max_value;
01892 device_data.minTanPressure = a[WAC_TAN_PRESSURE_I].min_value;
01893 device_data.maxTanPressure = a[WAC_TAN_PRESSURE_I].max_value;
01894 device_data.minZ = a[WAC_ZCOORD_I].min_value;
01895 device_data.maxZ = a[WAC_ZCOORD_I].max_value;
01896 #else
01897 device_data.minX = a[0].min_value;
01898 device_data.maxX = a[0].max_value;
01899 device_data.minY = a[1].min_value;
01900 device_data.maxY = a[1].max_value;
01901 device_data.minPressure = a[2].min_value;
01902 device_data.maxPressure = a[2].max_value;
01903 device_data.minTanPressure = 0;
01904 device_data.maxTanPressure = 0;
01905 device_data.minZ = 0;
01906 device_data.maxZ = 0;
01907 #endif
01908
01909
01910 break;
01911 }
01912 any = (XAnyClassPtr) ((char *) any + any->length);
01913 }
01914
01915 tablet_devices()->append(device_data);
01916 }
01917 }
01918 XFreeDeviceList(devices);
01919 }
01920 #endif // QT_NO_TABLET
01921
01922 X11->startupId = getenv("DESKTOP_STARTUP_ID");
01923 putenv(strdup("DESKTOP_STARTUP_ID="));
01924
01925 } else {
01926
01927
01928 if (QApplication::desktopSettingsAware()) {
01929 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
01930 settings.beginGroup(QLatin1String("Qt"));
01931
01932
01933 QString libpathkey = QString(QLatin1String("%1.%2/libraryPath"))
01934 .arg(QT_VERSION >> 16)
01935 .arg((QT_VERSION & 0xff00) >> 8);
01936 QStringList pathlist =
01937 settings.value(libpathkey).toString().split(QLatin1Char(':'));
01938 if (! pathlist.isEmpty()) {
01939 QStringList::ConstIterator it = pathlist.constBegin();
01940 while (it != pathlist.constEnd())
01941 QApplication::addLibraryPath(*it++);
01942 }
01943
01944 QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
01945 QVariant(QLatin1String("none"))).toString();
01946 if (defaultcodec != QLatin1String("none")) {
01947 QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
01948 if (codec)
01949 QTextCodec::setCodecForTr(codec);
01950 }
01951
01952 settings.endGroup();
01953 }
01954 }
01955 }
01956
01957
01958
01962 void QApplicationPrivate::x11_initialize_style()
01963 {
01964 if (QApplicationPrivate::app_style)
01965 return;
01966
01967 switch(X11->desktopEnvironment) {
01968 case DE_KDE:
01969 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("plastique"));
01970 break;
01971 case DE_GNOME:
01972 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("cleanlooks"));
01973 break;
01974 case DE_CDE:
01975 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("cde"));
01976 break;
01977 default:
01978
01979 break;
01980 }
01981 }
01982
01983 void QApplicationPrivate::initializeWidgetPaletteHash()
01984 {
01985 }
01986
01987
01988
01989
01990
01991 void qt_cleanup()
01992 {
01993 if (app_save_rootinfo)
01994 qt_save_rootinfo();
01995
01996 if (qt_is_gui_used) {
01997 QPixmapCache::clear();
01998 QCursorData::cleanup();
01999 QFont::cleanup();
02000 QColormap::cleanup();
02001 }
02002
02003 #ifndef QT_NO_XRENDER
02004 for (int i = 0; i < X11->solid_fill_count; ++i) {
02005 if (X11->solid_fills[i].picture)
02006 XRenderFreePicture(X11->display, X11->solid_fills[i].picture);
02007 }
02008 for (int i = 0; i < X11->pattern_fill_count; ++i) {
02009 if (X11->pattern_fills[i].picture)
02010 XRenderFreePicture(X11->display, X11->pattern_fills[i].picture);
02011 }
02012 #endif
02013 #if !defined (QT_NO_TABLET)
02014 QTabletDeviceDataList *devices = qt_tablet_devices();
02015 for (int i = 0; i < devices->size(); ++i)
02016 XCloseDevice(X11->display, (XDevice*)devices->at(i).device);
02017 #endif
02018
02019 #if !defined(QT_NO_IM)
02020 delete QApplicationPrivate::inputContext;
02021 QApplicationPrivate::inputContext = 0;
02022 #endif
02023
02024
02025 XSetErrorHandler(original_x_errhandler);
02026 XSetIOErrorHandler(original_xio_errhandler);
02027
02028 if (qt_is_gui_used && !X11->foreignDisplay)
02029 XCloseDisplay(X11->display);
02030 X11->display = 0;
02031
02032 delete [] X11->screens;
02033
02034 if (X11->foreignDisplay) {
02035 delete [] (char *)appName;
02036 appName = 0;
02037 }
02038
02039 delete [] (char *)appClass;
02040 appClass = 0;
02041
02042 if (X11->net_supported_list)
02043 delete [] X11->net_supported_list;
02044 X11->net_supported_list = 0;
02045
02046 if (X11->net_virtual_root_list)
02047 delete [] X11->net_virtual_root_list;
02048 X11->net_virtual_root_list = 0;
02049
02050 delete X11;
02051 X11 = 0;
02052 }
02053
02054
02055
02056
02057
02058
02059 void qt_save_rootinfo()
02060 {
02061 Atom type;
02062 int format;
02063 unsigned long length, after;
02064 uchar *data = 0;
02065
02066 if (ATOM(_XSETROOT_ID)) {
02067 if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
02068 ATOM(_XSETROOT_ID), 0, 1,
02069 True, AnyPropertyType, &type, &format,
02070 &length, &after, &data) == Success) {
02071 if (type == XA_PIXMAP && format == 32 && length == 1 &&
02072 after == 0 && data) {
02073 XKillClient(X11->display, *((Pixmap*)data));
02074 }
02075 Pixmap dummy = XCreatePixmap(X11->display, QX11Info::appRootWindow(),
02076 1, 1, 1);
02077 XChangeProperty(X11->display, QX11Info::appRootWindow(),
02078 ATOM(_XSETROOT_ID), XA_PIXMAP, 32,
02079 PropModeReplace, (uchar *)&dummy, 1);
02080 XSetCloseDownMode(X11->display, RetainPermanent);
02081 }
02082 }
02083 if (data)
02084 XFree((char *)data);
02085 }
02086
02087 void qt_updated_rootinfo()
02088 {
02089 app_save_rootinfo = true;
02090 }
02091
02092 bool qt_wstate_iconified(WId winid)
02093 {
02094 Atom type;
02095 int format;
02096 unsigned long length, after;
02097 uchar *data = 0;
02098 int r = XGetWindowProperty(X11->display, winid, ATOM(WM_STATE), 0, 2,
02099 False, AnyPropertyType, &type, &format,
02100 &length, &after, &data);
02101 bool iconic = false;
02102 if (r == Success && data && format == 32) {
02103
02104 unsigned long *wstate = (unsigned long *) data;
02105 iconic = (*wstate == IconicState);
02106 XFree((char *)data);
02107 }
02108 return iconic;
02109 }
02110
02111 QString QApplicationPrivate::appName() const
02112 {
02113 return QString::fromLocal8Bit(::appName);
02114 }
02115
02116 const char *QX11Info::appClass()
02117 {
02118 return ::appClass;
02119 }
02120
02121 bool qt_nograb()
02122 {
02123 #if defined(QT_DEBUG)
02124 return appNoGrab;
02125 #else
02126 return false;
02127 #endif
02128 }
02129
02130
02131
02132
02133
02134
02162 #ifdef QT3_SUPPORT
02163 void QApplication::setMainWidget(QWidget *mainWidget)
02164 {
02165 #ifndef QT_NO_DEBUG
02166 if (mainWidget && mainWidget->parentWidget() && mainWidget->isWindow())
02167 qWarning("QApplication::setMainWidget: New main widget (%s/%s) "
02168 "has a parent",
02169 mainWidget->metaObject()->className(), mainWidget->objectName().toLocal8Bit().constData());
02170 #endif
02171 mainWidget->d_func()->createWinId();
02172 QApplicationPrivate::main_widget = mainWidget;
02173 if (QApplicationPrivate::main_widget)
02174 QApplicationPrivate::applyX11SpecificCommandLineArguments(QApplicationPrivate::main_widget);
02175 }
02176 #endif
02177
02178 void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_widget)
02179 {
02180 static bool beenHereDoneThat = false;
02181 if (beenHereDoneThat)
02182 return;
02183 beenHereDoneThat = true;
02184 Q_ASSERT(main_widget->testAttribute(Qt::WA_WState_Created));
02185 XSetWMProperties(X11->display, main_widget->internalWinId(), 0, 0, qApp->d_func()->argv, qApp->d_func()->argc, 0, 0, 0);
02186 if (mwTitle) {
02187 XStoreName(X11->display, main_widget->internalWinId(), (char*)mwTitle);
02188 QByteArray net_wm_name = QString::fromLocal8Bit(mwTitle).toUtf8();
02189 XChangeProperty(X11->display, main_widget->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
02190 PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
02191 }
02192 if (mwGeometry) {
02193 int x, y;
02194 int w, h;
02195 int m = XParseGeometry((char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h);
02196 QSize minSize = main_widget->minimumSize();
02197 QSize maxSize = main_widget->maximumSize();
02198 if ((m & XValue) == 0)
02199 x = main_widget->geometry().x();
02200 if ((m & YValue) == 0)
02201 y = main_widget->geometry().y();
02202 if ((m & WidthValue) == 0)
02203 w = main_widget->width();
02204 if ((m & HeightValue) == 0)
02205 h = main_widget->height();
02206 w = qMin(w,maxSize.width());
02207 h = qMin(h,maxSize.height());
02208 w = qMax(w,minSize.width());
02209 h = qMax(h,minSize.height());
02210 if ((m & XNegative)) {
02211 x = QApplication::desktop()->width() + x - w;
02212 }
02213 if ((m & YNegative)) {
02214 y = QApplication::desktop()->height() + y - h;
02215 }
02216 main_widget->setGeometry(x, y, w, h);
02217 }
02218 }
02219
02220 #ifndef QT_NO_CURSOR
02221
02222
02223
02224
02225
02226 extern void qt_x11_enforce_cursor(QWidget * w);
02227
02257 void QApplication::setOverrideCursor(const QCursor &cursor)
02258 {
02259 qApp->d_func()->cursor_list.prepend(cursor);
02260
02261 QWidgetList all = allWidgets();
02262 for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
02263 register QWidget *w = *it;
02264 if (w->testAttribute(Qt::WA_SetCursor))
02265 qt_x11_enforce_cursor(w);
02266 }
02267 XFlush(X11->display);
02268 }
02269
02281 void QApplication::restoreOverrideCursor()
02282 {
02283 if (qApp->d_func()->cursor_list.isEmpty())
02284 return;
02285 qApp->d_func()->cursor_list.removeFirst();
02286
02287 if (QWidgetPrivate::mapper != 0 && !closingDown()) {
02288 QWidgetList all = allWidgets();
02289 for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
02290 register QWidget *w = *it;
02291 if (w->testAttribute(Qt::WA_SetCursor))
02292 qt_x11_enforce_cursor(w);
02293 }
02294 XFlush(X11->display);
02295 }
02296 }
02297
02298 #endif
02299
02300
02301
02302
02303
02304
02305 Window QX11Data::findClientWindow(Window win, Atom property, bool leaf)
02306 {
02307 Atom type = XNone;
02308 int format, i;
02309 ulong nitems, after;
02310 uchar *data = 0;
02311 Window root, parent, target=0, *children=0;
02312 uint nchildren;
02313 if (XGetWindowProperty(X11->display, win, property, 0, 0, false, AnyPropertyType,
02314 &type, &format, &nitems, &after, &data) == Success) {
02315 if (data)
02316 XFree((char *)data);
02317 if (type)
02318 return win;
02319 }
02320 if (!XQueryTree(X11->display,win,&root,&parent,&children,&nchildren)) {
02321 if (children)
02322 XFree((char *)children);
02323 return 0;
02324 }
02325 for (i=nchildren-1; !target && i >= 0; i--)
02326 target = X11->findClientWindow(children[i], property, leaf);
02327 if (children)
02328 XFree((char *)children);
02329 return target;
02330 }
02331
02332 QWidget *QApplication::topLevelAt(const QPoint &p)
02333 {
02334 int screen = QCursor::x11Screen();
02335 int unused;
02336
02337 int x = p.x();
02338 int y = p.y();
02339 Window target;
02340 if (!XTranslateCoordinates(X11->display,
02341 QX11Info::appRootWindow(screen),
02342 QX11Info::appRootWindow(screen),
02343 x, y, &unused, &unused, &target)) {
02344 return 0;
02345 }
02346 if (!target || target == QX11Info::appRootWindow(screen))
02347 return 0;
02348 QWidget *w;
02349 w = QWidget::find((WId)target);
02350
02351 if (!w) {
02352 X11->ignoreBadwindow();
02353 target = X11->findClientWindow(target, ATOM(WM_STATE), true);
02354 if (X11->badwindow())
02355 return 0;
02356 w = QWidget::find((WId)target);
02357 if (!w) {
02358
02359
02360 QWidgetList list = QApplication::topLevelWidgets();
02361 for (int i = 0; i < list.count(); ++i) {
02362 QWidget *widget = list.at(i);
02363 Window ctarget = target;
02364 if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
02365 Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
02366 Window wid = widget->internalWinId();
02367 while (ctarget && !w) {
02368 XTranslateCoordinates(X11->display,
02369 QX11Info::appRootWindow(screen),
02370 ctarget, x, y, &unused, &unused, &ctarget);
02371 if (ctarget == wid) {
02372
02373 w = widget;
02374 break;
02375 }
02376 }
02377 }
02378 if (w)
02379 break;
02380 }
02381 }
02382 }
02383 return w ? w->window() : 0;
02384 }
02385
02391 void QApplication::syncX()
02392 {
02393 if (X11->display)
02394 XSync(X11->display, False);
02395 }
02396
02397
02403 void QApplication::beep()
02404 {
02405 if (X11->display)
02406 XBell(X11->display, 0);
02407 else
02408 printf("\7");
02409 }
02410
02411
02412
02413
02414
02415
02416
02417 static QWidgetMapper *wPRmapper = 0;
02418
02419 void qPRCreate(const QWidget *widget, Window oldwin)
02420 {
02421 if (!wPRmapper)
02422 wPRmapper = new QWidgetMapper;
02423
02424 QETWidget *w = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
02425 wPRmapper->insert((int)oldwin, w);
02426 w->setAttribute(Qt::WA_WState_Reparented);
02427 }
02428
02429 void qPRCleanup(QWidget *widget)
02430 {
02431 QETWidget *etw = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
02432 if (!(wPRmapper && widget->testAttribute(Qt::WA_WState_Reparented)))
02433 return;
02434 for (QWidgetMapper::ConstIterator it = wPRmapper->constBegin(); it != wPRmapper->constEnd(); ++it) {
02435 QWidget *w = *it;
02436 int key = it.key();
02437 if (w == etw) {
02438 etw->setAttribute(Qt::WA_WState_Reparented, false);
02439 wPRmapper->remove(key);
02440 if (wPRmapper->size() == 0) {
02441 delete wPRmapper;
02442 wPRmapper = 0;
02443 }
02444 return;
02445 }
02446 }
02447 }
02448
02449 static QETWidget *qPRFindWidget(Window oldwin)
02450 {
02451 return wPRmapper ? (QETWidget*)wPRmapper->value((int)oldwin, 0) : 0;
02452 }
02453
02457 int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
02458 {
02459 QETWidget *widget = (QETWidget*)w;
02460 if (event->xclient.format == 32 && event->xclient.message_type) {
02461 if (event->xclient.message_type == ATOM(WM_PROTOCOLS)) {
02462 Atom a = event->xclient.data.l[0];
02463 if (a == ATOM(WM_DELETE_WINDOW)) {
02464 if (passive_only) return 0;
02465 widget->translateCloseEvent(event);
02466 }
02467 else if (a == ATOM(WM_TAKE_FOCUS)) {
02468 if ((ulong) event->xclient.data.l[1] > X11->time)
02469 X11->time = event->xclient.data.l[1];
02470 QWidget *amw = activeModalWidget();
02471 if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
02472 QWidget *p = amw->parentWidget();
02473 while (p && p != widget)
02474 p = p->parentWidget();
02475 if (!p || !X11->net_supported_list)
02476 amw->raise();
02477 amw->activateWindow();
02478 }
02479 #ifndef QT_NO_WHATSTHIS
02480 } else if (a == ATOM(_NET_WM_CONTEXT_HELP)) {
02481 QWhatsThis::enterWhatsThisMode();
02482 #endif // QT_NO_WHATSTHIS
02483 } else if (a == ATOM(_NET_WM_PING)) {
02484
02485 Window root = RootWindow(X11->display, w->x11Info().screen());
02486 if (event->xclient.window != root) {
02487 event->xclient.window = root;
02488 XSendEvent(event->xclient.display, event->xclient.window,
02489 False, SubstructureNotifyMask|SubstructureRedirectMask, event);
02490 }
02491 }
02492 } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
02493 widget->translateScrollDoneEvent(event);
02494 } else if (event->xclient.message_type == ATOM(XdndPosition)) {
02495 X11->xdndHandlePosition(widget, event, passive_only);
02496 } else if (event->xclient.message_type == ATOM(XdndEnter)) {
02497 X11->xdndHandleEnter(widget, event, passive_only);
02498 } else if (event->xclient.message_type == ATOM(XdndStatus)) {
02499 X11->xdndHandleStatus(widget, event, passive_only);
02500 } else if (event->xclient.message_type == ATOM(XdndLeave)) {
02501 X11->xdndHandleLeave(widget, event, passive_only);
02502 } else if (event->xclient.message_type == ATOM(XdndDrop)) {
02503 X11->xdndHandleDrop(widget, event, passive_only);
02504 } else if (event->xclient.message_type == ATOM(XdndFinished)) {
02505 X11->xdndHandleFinished(widget, event, passive_only);
02506 } else {
02507 if (passive_only) return 0;
02508
02509 }
02510 } else {
02511 X11->motifdndHandle(widget, event, passive_only);
02512 }
02513
02514 return 0;
02515 }
02516
02528 int QApplication::x11ProcessEvent(XEvent* event)
02529 {
02530 Q_D(QApplication);
02531 switch (event->type) {
02532 case ButtonPress:
02533 pressed_window = event->xbutton.window;
02534 X11->userTime = event->xbutton.time;
02535
02536 case ButtonRelease:
02537 X11->time = event->xbutton.time;
02538 break;
02539 case MotionNotify:
02540 X11->time = event->xmotion.time;
02541 break;
02542 case XKeyPress:
02543 X11->userTime = event->xkey.time;
02544
02545 case XKeyRelease:
02546 X11->time = event->xkey.time;
02547 break;
02548 case PropertyNotify:
02549 X11->time = event->xproperty.time;
02550 break;
02551 case EnterNotify:
02552 case LeaveNotify:
02553 X11->time = event->xcrossing.time;
02554 break;
02555 case SelectionClear:
02556 X11->time = event->xselectionclear.time;
02557 break;
02558 default:
02559 break;
02560 }
02561
02562 QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);
02563
02564 if (wPRmapper) {
02565 if (widget == 0) {
02566 switch (event->type) {
02567 case ButtonPress:
02568 case ButtonRelease:
02569 case MotionNotify:
02570 case XKeyPress:
02571 case XKeyRelease:
02572 widget = qPRFindWidget(event->xany.window);
02573 break;
02574 }
02575 }
02576 else if (widget->testAttribute(Qt::WA_WState_Reparented))
02577 qPRCleanup(widget);
02578 }
02579
02580 QETWidget *keywidget=0;
02581 bool grabbed=false;
02582 if (event->type==XKeyPress || event->type==XKeyRelease) {
02583 keywidget = (QETWidget*)QWidget::keyboardGrabber();
02584 if (keywidget) {
02585 grabbed = true;
02586 } else if (!keywidget) {
02587 if (d->inPopupMode())
02588 keywidget = (QETWidget*) (activePopupWidget()->focusWidget() ? activePopupWidget()->focusWidget() : activePopupWidget());
02589 else if (QApplicationPrivate::focus_widget)
02590 keywidget = (QETWidget*)QApplicationPrivate::focus_widget;
02591 else if (widget)
02592 keywidget = (QETWidget*)widget->window();
02593 }
02594 }
02595
02596 #ifndef QT_NO_IM
02597
02598
02599
02600
02601
02602
02603
02604
02605 if(keywidget && keywidget->isEnabled() && keywidget->testAttribute(Qt::WA_InputMethodEnabled)) {
02606
02607 if((event->type==XKeyPress || event->type==XKeyRelease) && qt_sm_blockUserInput)
02608 return true;
02609
02610
02611 QInputContext *qic = keywidget->inputContext();
02612 if(qic && qic->x11FilterEvent(keywidget, event))
02613 return true;
02614
02615
02616
02617
02618
02619
02620 if ((event->type == XKeyPress || event->type == XKeyRelease)) {
02621 int code = -1;
02622 int count = 0;
02623 Qt::KeyboardModifiers modifiers;
02624 QEvent::Type type;
02625 QString text;
02626 KeySym keySym;
02627
02628 qt_keymapper_private()->translateKeyEventInternal(keywidget, event, keySym, count,
02629 text, modifiers, code, type, false);
02630
02631
02632
02633 QKeyEventEx keyevent(type, code, modifiers, text, false, qMax(qMax(count, 1), text.length()),
02634 event->xkey.keycode, keySym, event->xkey.state);
02635 if(qic && qic->filterEvent(&keyevent))
02636 return true;
02637 }
02638 } else
02639 #endif // QT_NO_IM
02640 {
02641 if (XFilterEvent(event, XNone))
02642 return true;
02643 }
02644
02645 if (qt_x11EventFilter(event))
02646 return 1;
02647
02648 if (event->type == MappingNotify) {
02649
02650 XRefreshKeyboardMapping(&event->xmapping);
02651
02652 QKeyMapper::changeKeyboard();
02653 return 0;
02654 }
02655
02656 if (!widget) {
02657 QWidget* popup = QApplication::activePopupWidget();
02658 if (popup) {
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670 switch (event->type) {
02671 case ButtonPress:
02672 case ButtonRelease:
02673 case XKeyPress:
02674 case XKeyRelease:
02675 do {
02676 popup->close();
02677 } while ((popup = qApp->activePopupWidget()));
02678 return 1;
02679 }
02680 }
02681 return -1;
02682 }
02683
02684 if (event->type == XKeyPress || event->type == XKeyRelease)
02685 widget = keywidget;
02686
02687 if (app_do_modal)
02688 if (!qt_try_modal(widget, event)) {
02689 if (event->type == ClientMessage && !widget->x11Event(event))
02690 x11ClientMessage(widget, event, true);
02691 return 1;
02692 }
02693
02694
02695 if (widget->x11Event(event))
02696 return 1;
02697 #if !defined (QT_NO_TABLET)
02698 QTabletDeviceDataList *tablets = qt_tablet_devices();
02699 for (int i = 0; i < tablets->size(); ++i) {
02700 const QTabletDeviceData &tab = tablets->at(i);
02701 if (event->type == tab.xinput_motion
02702 || event->type == tab.xinput_button_release
02703 || event->type == tab.xinput_button_press
02704 || event->type == tab.xinput_proximity_in
02705 || event->type == tab.xinput_proximity_out) {
02706 widget->translateXinputEvent(event, &tab);
02707 return 0;
02708 }
02709 }
02710 #endif
02711
02712 #ifndef QT_NO_XRANDR
02713 if (X11->use_xrandr && event->type == (X11->xrandr_eventbase + RRScreenChangeNotify)) {
02714
02715 XRRUpdateConfiguration(event);
02716
02717
02718 int scr = XRRRootToScreen(X11->display, event->xany.window);
02719 QWidget *w = desktop()->screen(scr);
02720 QSize oldSize(w->size());
02721 w->data->crect.setWidth(DisplayWidth(X11->display, scr));
02722 w->data->crect.setHeight(DisplayHeight(X11->display, scr));
02723 if (w->size() != oldSize) {
02724 QResizeEvent e(w->size(), oldSize);
02725 QApplication::sendEvent(w, &e);
02726 emit desktop()->resized(scr);
02727 }
02728 }
02729 #endif // QT_NO_XRANDR
02730
02731 switch (event->type) {
02732
02733 case ButtonRelease:
02734 if (!d->inPopupMode() && !QWidget::mouseGrabber() && pressed_window != widget->internalWinId()
02735 && (widget = (QETWidget*) QWidget::find((WId)pressed_window)) == 0)
02736 break;
02737
02738 case ButtonPress:
02739 if (event->xbutton.root != RootWindow(X11->display, widget->x11Info().screen())
02740 && ! qt_xdnd_dragging) {
02741 while (activePopupWidget())
02742 activePopupWidget()->close();
02743 return 1;
02744 }
02745 if (event->type == ButtonPress)
02746 qt_net_update_user_time(widget->window());
02747
02748 case MotionNotify:
02749 #if !defined(QT_NO_TABLET)
02750 if (!qt_tabletChokeMouse) {
02751 #endif
02752 if (widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
02753 QPoint pos(event->xbutton.x, event->xbutton.y);
02754 pos = widget->d_func()->mapFromWS(pos);
02755 QWidget *window = widget->window();
02756 pos = widget->mapTo(window, pos);
02757 if (QWidget *child = window->childAt(pos)) {
02758 widget = static_cast<QETWidget *>(child);
02759 pos = child->mapFrom(window, pos);
02760 event->xbutton.x = pos.x();
02761 event->xbutton.y = pos.y();
02762 }
02763 }
02764 widget->translateMouseEvent(event);
02765 #if !defined(QT_NO_TABLET)
02766 } else {
02767 qt_tabletChokeMouse = false;
02768 }
02769 #endif
02770 break;
02771
02772 case XKeyPress:
02773 qt_net_update_user_time(widget->window());
02774
02775 case XKeyRelease:
02776 {
02777 if (keywidget && keywidget->isEnabled()) {
02778
02779 qt_keymapper_private()->translateKeyEvent(keywidget, event, grabbed);
02780 }
02781 break;
02782 }
02783
02784 case GraphicsExpose:
02785 case Expose:
02786 widget->translatePaintEvent(event);
02787 break;
02788
02789 case ConfigureNotify:
02790 if (event->xconfigure.event == event->xconfigure.window)
02791 widget->translateConfigEvent(event);
02792 break;
02793
02794 case XFocusIn: {
02795 if ((widget->windowType() == Qt::Desktop))
02796 break;
02797 if (d->inPopupMode())
02798 break;
02799 if (!widget->isWindow())
02800 break;
02801 if (event->xfocus.detail != NotifyAncestor &&
02802 event->xfocus.detail != NotifyInferior &&
02803 event->xfocus.detail != NotifyNonlinear)
02804 break;
02805 setActiveWindow(widget);
02806 if (X11->focus_model == QX11Data::FM_PointerRoot) {
02807
02808
02809
02810 qt_check_focus_model();
02811 }
02812 }
02813 break;
02814
02815 case XFocusOut:
02816 if ((widget->windowType() == Qt::Desktop))
02817 break;
02818 if (!widget->isWindow())
02819 break;
02820 if (event->xfocus.mode == NotifyGrab) {
02821 qt_xfocusout_grab_counter++;
02822 break;
02823 }
02824 if (event->xfocus.detail != NotifyAncestor &&
02825 event->xfocus.detail != NotifyNonlinearVirtual &&
02826 event->xfocus.detail != NotifyNonlinear)
02827 break;
02828 if (!d->inPopupMode() && widget == QApplicationPrivate::active_window)
02829 setActiveWindow(0);
02830 break;
02831
02832 case EnterNotify: {
02833 if (QWidget::mouseGrabber() && widget != QWidget::mouseGrabber())
02834 break;
02835 if (d->inPopupMode() && widget->window() != activePopupWidget())
02836 break;
02837 if (event->xcrossing.mode != NotifyNormal ||
02838 event->xcrossing.detail == NotifyVirtual ||
02839 event->xcrossing.detail == NotifyNonlinearVirtual)
02840 break;
02841 if (event->xcrossing.focus &&
02842 !(widget->windowType() == Qt::Desktop) && !widget->isActiveWindow()) {
02843 if (X11->focus_model == QX11Data::FM_Unknown)
02844 qt_check_focus_model();
02845 if (X11->focus_model == QX11Data::FM_PointerRoot)
02846 setActiveWindow(widget);
02847 }
02848 QApplicationPrivate::dispatchEnterLeave(widget, QWidget::find(curWin));
02849 curWin = widget->internalWinId();
02850 widget->translateMouseEvent(event);
02851 }
02852 break;
02853
02854 case LeaveNotify: {
02855 if (QWidget::mouseGrabber() && widget != QWidget::mouseGrabber())
02856 break;
02857 if (curWin && widget->internalWinId() != curWin)
02858 break;
02859 if (event->xcrossing.mode != NotifyNormal)
02860 break;
02861 if (!(widget->windowType() == Qt::Desktop))
02862 widget->translateMouseEvent(event);
02863
02864 QWidget* enter = 0;
02865 XEvent ev;
02866 while (XCheckMaskEvent(X11->display, EnterWindowMask | LeaveWindowMask , &ev)
02867 && !qt_x11EventFilter(&ev)) {
02868 QWidget* event_widget = QWidget::find(ev.xcrossing.window);
02869 if(event_widget && event_widget->x11Event(&ev))
02870 break;
02871 if (ev.type == LeaveNotify
02872 || ev.xcrossing.mode != NotifyNormal
02873 || ev.xcrossing.detail == NotifyVirtual
02874 || ev.xcrossing.detail == NotifyNonlinearVirtual)
02875 continue;
02876 enter = event_widget;
02877 if (ev.xcrossing.focus &&
02878 enter && !(enter->windowType() == Qt::Desktop) && !enter->isActiveWindow()) {
02879 if (X11->focus_model == QX11Data::FM_Unknown)
02880 qt_check_focus_model();
02881 if (X11->focus_model == QX11Data::FM_PointerRoot)
02882 setActiveWindow(enter);
02883 }
02884 break;
02885 }
02886
02887 if ((! enter || (enter->windowType() == Qt::Desktop)) &&
02888 event->xcrossing.focus && widget == QApplicationPrivate::active_window &&
02889 X11->focus_model == QX11Data::FM_PointerRoot
02890 ) {
02891 setActiveWindow(0);
02892 }
02893
02894 if (!curWin)
02895 QApplicationPrivate::dispatchEnterLeave(widget, 0);
02896
02897 QApplicationPrivate::dispatchEnterLeave(enter, widget);
02898 if (enter && QApplicationPrivate::tryModalHelper(enter, 0)) {
02899 curWin = enter->internalWinId();
02900 static_cast<QETWidget *>(enter)->translateMouseEvent(&ev);
02901 } else {
02902 curWin = 0;
02903 }
02904 }
02905 break;
02906
02907 case UnmapNotify:
02908 if (widget->isWindow()) {
02909 Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
02910 widget->d_func()->topData()->waitingForMapNotify = 0;
02911
02912 if (widget->windowType() != Qt::Popup) {
02913 widget->setAttribute(Qt::WA_Mapped, false);
02914 if (widget->isVisible()) {
02915 widget->d_func()->topData()->spont_unmapped = 1;
02916 QHideEvent e;
02917 QApplication::sendSpontaneousEvent(widget, &e);
02918 widget->d_func()->hideChildren(true);
02919 }
02920 }
02921
02922 if (!widget->d_func()->topData()->validWMState) {
02923 int idx = X11->deferred_map.indexOf(widget);
02924 if (idx != -1) {
02925 X11->deferred_map.removeAt(idx);
02926 Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
02927 XMapWindow(X11->display, widget->internalWinId());
02928 }
02929 }
02930 }
02931 break;
02932
02933 case MapNotify:
02934 if (widget->isWindow()) {
02935 widget->d_func()->topData()->waitingForMapNotify = 0;
02936
02937 if (widget->windowType() != Qt::Popup) {
02938 widget->setAttribute(Qt::WA_Mapped);
02939 if (widget->d_func()->topData()->spont_unmapped) {
02940 widget->d_func()->topData()->spont_unmapped = 0;
02941 widget->d_func()->showChildren(true);
02942 QShowEvent e;
02943 QApplication::sendSpontaneousEvent(widget, &e);
02944
02945
02946
02947
02948
02949
02950 widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
02951 widget->setAttribute(Qt::WA_WState_Visible, true);
02952 }
02953 }
02954 }
02955 break;
02956
02957 case ClientMessage:
02958 return x11ClientMessage(widget,event,False);
02959
02960 case ReparentNotify:
02961 while (XCheckTypedWindowEvent(X11->display,
02962 widget->internalWinId(),
02963 ReparentNotify,
02964 event))
02965 ;
02966 if (widget->isWindow()) {
02967 QTLWExtra *topData = widget->d_func()->topData();
02968
02969
02970 topData->parentWinId = event->xreparent.parent;
02971
02972
02973 topData->frameStrut.setCoords(0, 0, 0, 0);
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986 if (topData->waitingForMapNotify && !topData->validWMState)
02987 topData->validWMState = 1;
02988
02989 if (X11->focus_model != QX11Data::FM_Unknown) {
02990
02991 QWidget *newparent = QWidget::find(event->xreparent.parent);
02992 if (! newparent || (newparent->windowType() == Qt::Desktop)) {
02993
02994
02995
02996 X11->focus_model = QX11Data::FM_Unknown;
02997 }
02998 }
02999 }
03000 break;
03001
03002 case SelectionRequest: {
03003 XSelectionRequestEvent *req = &event->xselectionrequest;
03004 if (! req)
03005 break;
03006
03007 if (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)) {
03008 X11->xdndHandleSelectionRequest(req);
03009
03010 } else if (qt_clipboard) {
03011 QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
03012 QApplication::sendSpontaneousEvent(qt_clipboard, &e);
03013 }
03014 break;
03015 }
03016 case SelectionClear: {
03017 XSelectionClearEvent *req = &event->xselectionclear;
03018
03019 if (! req || ATOM(XdndSelection) && req->selection == ATOM(XdndSelection))
03020 break;
03021
03022 if (qt_clipboard) {
03023 QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
03024 QApplication::sendSpontaneousEvent(qt_clipboard, &e);
03025 }
03026 break;
03027 }
03028
03029 case SelectionNotify: {
03030 XSelectionEvent *req = &event->xselection;
03031
03032 if (! req || ATOM(XdndSelection) && req->selection == ATOM(XdndSelection))
03033 break;
03034
03035 if (qt_clipboard) {
03036 QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
03037 QApplication::sendSpontaneousEvent(qt_clipboard, &e);
03038 }
03039 break;
03040 }
03041
03042 case PropertyNotify:
03043
03044 if (event->xproperty.window == QX11Info::appRootWindow(0)) {
03045
03046 if (event->xproperty.atom == ATOM(_QT_CLIPBOARD_SENTINEL)) {
03047 if (qt_check_clipboard_sentinel())
03048 emit clipboard()->dataChanged();
03049 } else if (event->xproperty.atom == ATOM(_QT_SELECTION_SENTINEL)) {
03050 if (qt_check_selection_sentinel())
03051 emit clipboard()->selectionChanged();
03052 } else if (QApplicationPrivate::obey_desktop_settings) {
03053 if (event->xproperty.atom == ATOM(RESOURCE_MANAGER))
03054 qt_set_x11_resources();
03055 else if (event->xproperty.atom == ATOM(_QT_SETTINGS_TIMESTAMP))
03056 QApplicationPrivate::x11_apply_settings();
03057 }
03058 }
03059 if (event->xproperty.window == QX11Info::appRootWindow()) {
03060
03061 if (event->xproperty.atom == ATOM(_QT_INPUT_ENCODING)) {
03062 qt_set_input_encoding();
03063 } else if (event->xproperty.atom == ATOM(_NET_SUPPORTED)) {
03064 qt_get_net_supported();
03065 } else if (event->xproperty.atom == ATOM(_NET_VIRTUAL_ROOTS)) {
03066 qt_get_net_virtual_roots();
03067 } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) {
03068 qt_desktopwidget_update_workarea();
03069 }
03070 } else if (widget) {
03071 widget->translatePropertyEvent(event);
03072 } else {
03073 return -1;
03074 }
03075 break;
03076
03077 default:
03078 break;
03079 }
03080
03081 return 0;
03082 }
03083
03101 bool QApplication::x11EventFilter(XEvent *)
03102 {
03103 return false;
03104 }
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125 bool QApplicationPrivate::modalState()
03126 {
03127 return app_do_modal;
03128 }
03129
03130 void QApplicationPrivate::enterModal_sys(QWidget *widget)
03131 {
03132 if (!qt_modal_stack)
03133 qt_modal_stack = new QWidgetList;
03134
03135 QApplicationPrivate::dispatchEnterLeave(0, QWidget::find((WId)curWin));
03136 qt_modal_stack->insert(0, widget);
03137 app_do_modal = true;
03138 curWin = 0;
03139 }
03140
03141 void QApplicationPrivate::leaveModal_sys(QWidget *widget)
03142 {
03143 if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
03144 if (qt_modal_stack->isEmpty()) {
03145 delete qt_modal_stack;
03146 qt_modal_stack = 0;
03147 QPoint p(QCursor::pos());
03148 QWidget* w = QApplication::widgetAt(p.x(), p.y());
03149 QApplicationPrivate::dispatchEnterLeave(w, QWidget::find(curWin));
03150 curWin = w? w->internalWinId() : 0;
03151 }
03152 }
03153 app_do_modal = qt_modal_stack != 0;
03154 }
03155
03156 bool qt_try_modal(QWidget *widget, XEvent *event)
03157 {
03158 if (qt_xdnd_dragging) {
03159
03160 switch (event->type) {
03161 case ButtonPress:
03162 case ButtonRelease:
03163 case MotionNotify:
03164 return true;
03165 default:
03166 break;
03167 }
03168 }
03169
03170
03171 if (event->type == ButtonRelease && widget == qt_button_down)
03172 return true;
03173
03174 if (QApplicationPrivate::tryModalHelper(widget))
03175 return true;
03176
03177
03178 switch (event->type) {
03179 case ButtonPress:
03180 case ButtonRelease:
03181 case MotionNotify:
03182 case XKeyPress:
03183 case XKeyRelease:
03184 case EnterNotify:
03185 case LeaveNotify:
03186 case ClientMessage:
03187 return false;
03188 default:
03189 break;
03190 }
03191
03192 return true;
03193 }
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211 static int openPopupCount = 0;
03212 void QApplicationPrivate::openPopup(QWidget *popup)
03213 {
03214 Q_Q(QApplication);
03215 openPopupCount++;
03216 if (!QApplicationPrivate::popupWidgets) {
03217 QApplicationPrivate::popupWidgets = new QWidgetList;
03218 }
03219 QApplicationPrivate::popupWidgets->append(popup);
03220 Display *dpy = X11->display;
03221 if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){
03222 Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
03223 int r = XGrabKeyboard(dpy, popup->internalWinId(), false,
03224 GrabModeAsync, GrabModeAsync, X11->time);
03225 if ((popupGrabOk = (r == GrabSuccess))) {
03226 r = XGrabPointer(dpy, popup->internalWinId(), true,
03227 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
03228 | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
03229 GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
03230 if (!(popupGrabOk = (r == GrabSuccess)))
03231 XUngrabKeyboard(dpy, X11->time);
03232 }
03233 }
03234
03235
03236
03237
03238 if (popup->focusWidget()) {
03239 popup->focusWidget()->setFocus(Qt::PopupFocusReason);
03240 } else if (QApplicationPrivate::popupWidgets->count() == 1) {
03241 if (QWidget *fw = QApplication::focusWidget()) {
03242 QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
03243 q->sendEvent(fw, &e);
03244 }
03245 }
03246 }
03247
03248 void QApplicationPrivate::closePopup(QWidget *popup)
03249 {
03250 Q_Q(QApplication);
03251 if (!QApplicationPrivate::popupWidgets)
03252 return;
03253 QApplicationPrivate::popupWidgets->removeAll(popup);
03254 if (popup == qt_popup_down) {
03255 qt_button_down = 0;
03256 qt_popup_down = 0;
03257 }
03258 if (QApplicationPrivate::popupWidgets->count() == 0) {
03259 delete QApplicationPrivate::popupWidgets;
03260 QApplicationPrivate::popupWidgets = 0;
03261 if (!qt_nograb() && popupGrabOk) {
03262 Display *dpy = X11->display;
03263 if (popup->geometry().contains(QPoint(mouseGlobalXPos, mouseGlobalYPos))
03264 || popup->testAttribute(Qt::WA_NoMouseReplay)) {
03265
03266 replayPopupMouseEvent = false;
03267 } else {
03268 mouseButtonPressTime -= 10000;
03269 replayPopupMouseEvent = true;
03270 }
03271 XUngrabPointer(dpy, X11->time);
03272 XUngrabKeyboard(dpy, X11->time);
03273 XFlush(dpy);
03274 }
03275 if (QApplicationPrivate::active_window) {
03276 if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
03277 if (fw != QApplication::focusWidget()) {
03278 fw->setFocus(Qt::PopupFocusReason);
03279 } else {
03280 QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
03281 q->sendEvent(fw, &e);
03282 }
03283 }
03284 }
03285 } else {
03286
03287
03288
03289
03290 QWidget* aw = QApplicationPrivate::popupWidgets->last();
03291 if (QWidget *fw = aw->focusWidget())
03292 fw->setFocus(Qt::PopupFocusReason);
03293
03294
03295 if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){
03296 Display *dpy = X11->display;
03297 Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
03298 int r = XGrabKeyboard(dpy, aw->internalWinId(), false,
03299 GrabModeAsync, GrabModeAsync, X11->time);
03300 if ((popupGrabOk = (r == GrabSuccess))) {
03301 r = XGrabPointer(dpy, aw->internalWinId(), true,
03302 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
03303 | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
03304 GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
03305 if (!(popupGrabOk = (r == GrabSuccess)))
03306 XUngrabKeyboard(dpy, X11->time);
03307 }
03308 }
03309 }
03310 }
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323 static Qt::MouseButtons translateMouseButtons(int s)
03324 {
03325 Qt::MouseButtons ret = 0;
03326 if (s & Button1Mask)
03327 ret |= Qt::LeftButton;
03328 if (s & Button2Mask)
03329 ret |= Qt::MidButton;
03330 if (s & Button3Mask)
03331 ret |= Qt::RightButton;
03332 return ret;
03333 }
03334
03335 Qt::KeyboardModifiers QX11Data::translateModifiers(int s)
03336 {
03337 Qt::KeyboardModifiers ret = 0;
03338 if (s & ShiftMask)
03339 ret |= Qt::ShiftModifier;
03340 if (s & ControlMask)
03341 ret |= Qt::ControlModifier;
03342 if (s & qt_alt_mask)
03343 ret |= Qt::AltModifier;
03344 if (s & qt_meta_mask)
03345 ret |= Qt::MetaModifier;
03346 if (s & qt_mode_switch_mask)
03347 ret |= Qt::GroupSwitchModifier;
03348 return ret;
03349 }
03350
03351 bool QETWidget::translateMouseEvent(const XEvent *event)
03352 {
03353 Q_D(QWidget);
03354 static bool manualGrab = false;
03355 QEvent::Type type;
03356 QPoint pos;
03357 QPoint globalPos;
03358 Qt::MouseButton button = Qt::NoButton;
03359 Qt::MouseButtons buttons;
03360 Qt::KeyboardModifiers modifiers;
03361 XEvent nextEvent;
03362
03363 if (qt_sm_blockUserInput)
03364 return true;
03365
03366 if (event->type == MotionNotify) {
03367 if (event->xmotion.root != RootWindow(X11->display, x11Info().screen()) &&
03368 ! qt_xdnd_dragging)
03369 return false;
03370
03371 XMotionEvent lastMotion = event->xmotion;
03372 while(XPending(X11->display)) {
03373 XNextEvent(X11->display, &nextEvent);
03374 if (nextEvent.type == ConfigureNotify
03375 || nextEvent.type == PropertyNotify
03376 || nextEvent.type == Expose
03377 || nextEvent.type == GraphicsExpose
03378 || nextEvent.type == NoExpose
03379 || nextEvent.type == KeymapNotify
03380 || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify)
03381 && qt_button_down == this)
03382 || (nextEvent.type == ClientMessage
03383 && nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE))) {
03384 qApp->x11ProcessEvent(&nextEvent);
03385 continue;
03386 } else if (nextEvent.type != MotionNotify ||
03387 nextEvent.xmotion.window != event->xmotion.window ||
03388 nextEvent.xmotion.state != event->xmotion.state) {
03389 XPutBackEvent(X11->display, &nextEvent);
03390 break;
03391 }
03392 if (!qt_x11EventFilter(&nextEvent)
03393 && !x11Event(&nextEvent))
03394 lastMotion = nextEvent.xmotion;
03395 else
03396 break;
03397 }
03398 type = QEvent::MouseMove;
03399 pos.rx() = lastMotion.x;
03400 pos.ry() = lastMotion.y;
03401 pos = d->mapFromWS(pos);
03402 globalPos.rx() = lastMotion.x_root;
03403 globalPos.ry() = lastMotion.y_root;
03404 buttons = translateMouseButtons(lastMotion.state);
03405 modifiers = X11->translateModifiers(lastMotion.state);
03406 if (qt_button_down && !buttons)
03407 qt_button_down = 0;
03408 } else if (event->type == EnterNotify || event->type == LeaveNotify) {
03409 XEvent *xevent = (XEvent *)event;
03410
03411 type = QEvent::MouseMove;
03412 pos.rx() = xevent->xcrossing.x;
03413 pos.ry() = xevent->xcrossing.y;
03414 pos = d->mapFromWS(pos);
03415 globalPos.rx() = xevent->xcrossing.x_root;
03416 globalPos.ry() = xevent->xcrossing.y_root;
03417 buttons = translateMouseButtons(xevent->xcrossing.state);
03418 modifiers = X11->translateModifiers(xevent->xcrossing.state);
03419 if (qt_button_down && !buttons)
03420 qt_button_down = 0;
03421 if (qt_button_down)
03422 return true;
03423 } else {
03424 pos.rx() = event->xbutton.x;
03425 pos.ry() = event->xbutton.y;
03426 pos = d->mapFromWS(pos);
03427 globalPos.rx() = event->xbutton.x_root;
03428 globalPos.ry() = event->xbutton.y_root;
03429 buttons = translateMouseButtons(event->xbutton.state);
03430 modifiers = X11->translateModifiers(event->xbutton.state);
03431 switch (event->xbutton.button) {
03432 case Button1: button = Qt::LeftButton; break;
03433 case Button2: button = Qt::MidButton; break;
03434 case Button3: button = Qt::RightButton; break;
03435 case Button4:
03436 case Button5:
03437 case 6:
03438 case 7:
03439
03440
03441
03442 if (event->type == ButtonPress){
03443
03444
03445
03446
03447 int delta = 1;
03448 XEvent xevent;
03449 while (XCheckTypedWindowEvent(X11->display, internalWinId(), ButtonPress, &xevent)){
03450 if (xevent.xbutton.button != event->xbutton.button){
03451 XPutBackEvent(X11->display, &xevent);
03452 break;
03453 }
03454 delta++;
03455 }
03456
03457
03458
03459
03460
03461
03462 int btn = event->xbutton.button;
03463 delta *= 120 * ((btn == Button4 || btn == 6) ? 1 : -1);
03464 bool hor = ((btn == Button4 || btn == Button5) && (modifiers & Qt::AltModifier) ||
03465 (btn == 6 || btn == 7));
03466 translateWheelEvent(globalPos.x(), globalPos.y(), delta, buttons,
03467 modifiers, (hor) ? Qt::Horizontal: Qt::Vertical);
03468 }
03469 return true;
03470 case 8: button = Qt::XButton1; break;
03471 case 9: button = Qt::XButton2; break;
03472 }
03473 if (event->type == ButtonPress) {
03474 buttons |= button;
03475 #if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
03476 TabletDeviceDataList *tablets = qt_tablet_devices();
03477 for (int i = 0; i < tablets->size(); ++i) {
03478 const TabletDeviceData &tab = tablets->at(i);
03479 XEvent myEv;
03480 if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
03481 if (translateXinputEvent(&myEv, &tab)) {
03482
03483 if (qt_tabletChokeMouse) {
03484 qt_tabletChokeMouse = false;
03485 return false;
03486 }
03487 }
03488 }
03489 }
03490 #endif
03491 qt_button_down = childAt(pos);
03492 if (!qt_button_down)
03493 qt_button_down = this;
03494 if (mouseActWindow == event->xbutton.window &&
03495 mouseButtonPressed == button &&
03496 (long)event->xbutton.time -(long)mouseButtonPressTime
03497 < QApplication::doubleClickInterval() &&
03498 qAbs(event->xbutton.x - mouseXPos) < 5 &&
03499 qAbs(event->xbutton.y - mouseYPos) < 5) {
03500 type = QEvent::MouseButtonDblClick;
03501 mouseButtonPressTime -= 2000;
03502 } else {
03503 type = QEvent::MouseButtonPress;
03504 mouseButtonPressTime = event->xbutton.time;
03505 }
03506 mouseButtonPressed = button;
03507 mouseXPos = event->xbutton.x;
03508 mouseYPos = event->xbutton.y;
03509 mouseGlobalXPos = globalPos.x();
03510 mouseGlobalYPos = globalPos.y();
03511 } else {
03512 buttons &= ~button;
03513 #if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
03514 TabletDeviceDataList *tablets = qt_tablet_devices();
03515 for (int i = 0; i < tablets->size(); ++i) {
03516 const TabletDeviceData &tab = tablets->at(i);
03517 XEvent myEv;
03518 if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
03519 if (translateXinputEvent(&myEv, &tab)) {
03520
03521 if (qt_tabletChokeMouse) {
03522 qt_tabletChokeMouse = false;
03523 return false;
03524 }
03525 }
03526 }
03527 }
03528 #endif
03529 if (manualGrab) {
03530 manualGrab = false;
03531 XUngrabPointer(X11->display, X11->time);
03532 XFlush(X11->display);
03533 }
03534
03535 type = QEvent::MouseButtonRelease;
03536 }
03537 }
03538 mouseActWindow = internalWinId();
03539 mouseButtonState = buttons;
03540 if (type == 0)
03541 return false;
03542
03543 if (qApp->d_func()->inPopupMode()) {
03544 QWidget *activePopupWidget = qApp->activePopupWidget();
03545 QWidget *popup = qApp->activePopupWidget();
03546 if (popup != this) {
03547 if (event->type == LeaveNotify)
03548 return false;
03549 if ((windowType() == Qt::Popup) && rect().contains(pos))
03550 popup = this;
03551 else
03552 pos = popup->mapFromGlobal(globalPos);
03553 }
03554 bool releaseAfter = false;
03555 QWidget *popupChild = popup->childAt(pos);
03556
03557 if (popup != qt_popup_down){
03558 qt_button_down = 0;
03559 qt_popup_down = 0;
03560 }
03561
03562 switch (type) {
03563 case QEvent::MouseButtonPress:
03564 case QEvent::MouseButtonDblClick:
03565 qt_button_down = popupChild;
03566 qt_popup_down = popup;
03567 break;
03568 case QEvent::MouseButtonRelease:
03569 releaseAfter = true;
03570 break;
03571 default:
03572 break;
03573 }
03574
03575 int oldOpenPopupCount = openPopupCount;
03576
03577
03578 replayPopupMouseEvent = false;
03579 if (qt_button_down) {
03580 QMouseEvent e(type, qt_button_down->mapFromGlobal(globalPos),
03581 globalPos, button, buttons, modifiers);
03582 QApplication::sendSpontaneousEvent(qt_button_down, &e);
03583 } else if (popupChild) {
03584 QMouseEvent e(type, popupChild->mapFromGlobal(globalPos),
03585 globalPos, button, buttons, modifiers);
03586 QApplication::sendSpontaneousEvent(popupChild, &e);
03587 } else {
03588 QMouseEvent e(type, pos, globalPos, button, buttons, modifiers);
03589 QApplication::sendSpontaneousEvent(popup, &e);
03590 }
03591
03592 if (qApp->activePopupWidget() != activePopupWidget
03593 && replayPopupMouseEvent) {
03594
03595 if (!(windowType() == Qt::Popup)) {
03596 if (buttons == button)
03597 qt_button_down = this;
03598 QMouseEvent e(type, mapFromGlobal(globalPos), globalPos, button,
03599 buttons, modifiers);
03600 QApplication::sendSpontaneousEvent(this, &e);
03601
03602 if (type == QEvent::MouseButtonPress
03603 && button == Qt::RightButton
03604 && (openPopupCount == oldOpenPopupCount)) {
03605 QContextMenuEvent e(QContextMenuEvent::Mouse, mapFromGlobal(globalPos), globalPos);
03606 QApplication::sendSpontaneousEvent(this, &e);
03607 }
03608 }
03609 replayPopupMouseEvent = false;
03610 } else if (type == QEvent::MouseButtonPress
03611 && button == Qt::RightButton
03612 && (openPopupCount == oldOpenPopupCount)) {
03613 QWidget *popupEvent = popup;
03614 if (qt_button_down)
03615 popupEvent = qt_button_down;
03616 else if(popupChild)
03617 popupEvent = popupChild;
03618 QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos);
03619 QApplication::sendSpontaneousEvent(popupEvent, &e);
03620 }
03621
03622 if (releaseAfter) {
03623 qt_button_down = 0;
03624 qt_popup_down = 0;
03625 }
03626 if (!qApp->d_func()->inPopupMode()) {
03627 if (type != QEvent::MouseButtonRelease && !buttons &&
03628 QWidget::find((WId)mouseActWindow)) {
03629 manualGrab = true;
03630 XGrabPointer(X11->display, mouseActWindow, False,
03631 (uint)(ButtonPressMask | ButtonReleaseMask |
03632 ButtonMotionMask |
03633 EnterWindowMask | LeaveWindowMask),
03634 GrabModeAsync, GrabModeAsync,
03635 XNone, XNone, CurrentTime);
03636 }
03637 }
03638
03639 } else {
03640 QWidget *widget = this;
03641 QWidget *w = QWidget::mouseGrabber();
03642
03643 if (((type == QEvent::MouseMove && buttons)
03644 || (type == QEvent::MouseButtonRelease))
03645 && !qt_button_down && !w)
03646 return false;
03647
03648
03649 if (!w)
03650 w = qt_button_down;
03651
03652 if (w && w != this) {
03653 widget = w;
03654 pos = w->mapFromGlobal(globalPos);
03655 }
03656
03657
03658 if (type == QEvent::MouseButtonRelease && !buttons) {
03659
03660 qt_button_down = 0;
03661 }
03662
03663 int oldOpenPopupCount = openPopupCount;
03664
03665 QMouseEvent e(type, pos, globalPos, button, buttons, modifiers);
03666 QApplication::sendSpontaneousEvent(widget, &e);
03667
03668 if (type == QEvent::MouseButtonPress
03669 && button == Qt::RightButton
03670 && (openPopupCount == oldOpenPopupCount)) {
03671 QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos);
03672 QApplication::sendSpontaneousEvent(widget, &e);
03673 }
03674 }
03675 return true;
03676 }
03677
03678
03679
03680
03681
03682 bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
03683 Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
03684 Qt::Orientation orient)
03685 {
03686
03687 {
03688 QWidget* popup = qApp->activePopupWidget();
03689 if (popup && window() != popup)
03690 popup->close();
03691 QWheelEvent e(mapFromGlobal(QPoint(global_x, global_y)),
03692 QPoint(global_x, global_y), delta, buttons, modifiers, orient);
03693 if (QApplication::sendSpontaneousEvent(this, &e))
03694 return true;
03695 }
03696
03697
03698 QWidget *w = this;
03699 if (w != qApp->focusWidget() && (w = qApp->focusWidget())) {
03700 QWidget* popup = qApp->activePopupWidget();
03701 if (popup && w != popup)
03702 popup->hide();
03703 QWheelEvent e(mapFromGlobal(QPoint(global_x, global_y)),
03704 QPoint(global_x, global_y), delta, buttons, modifiers, orient);
03705 if (QApplication::sendSpontaneousEvent(w, &e))
03706 return true;
03707 }
03708 return false;
03709 }
03710
03711
03712
03713
03714
03715 #if !defined (QT_NO_TABLET)
03716 bool QETWidget::translateXinputEvent(const XEvent *ev, const QTabletDeviceData *tablet)
03717 {
03718 #if defined (Q_OS_IRIX)
03719
03720
03721
03722 XDeviceState *s;
03723 XInputClass *iClass;
03724 XValuatorState *vs;
03725 int j;
03726 #endif
03727
03728 Q_ASSERT(tablet != 0);
03729
03730 QWidget *w = this;
03731 QPoint global,
03732 curr;
03733 QPointF hiRes;
03734 qreal pressure = 0;
03735 int xTilt = 0,
03736 yTilt = 0,
03737 z = 0;
03738 qreal tangentialPressure = 0;
03739 qreal rotation = 0;
03740 int deviceType = QTabletEvent::NoDevice;
03741 int pointerType = QTabletEvent::UnknownPointer;
03742 XEvent xinputMotionEvent;
03743 XEvent mouseMotionEvent;
03744 const XDeviceMotionEvent *motion = 0;
03745 XDeviceButtonEvent *button = 0;
03746 const XProximityNotifyEvent *proximity = 0;
03747 QEvent::Type t;
03748 Qt::KeyboardModifiers modifiers = 0;
03749 #if !defined (Q_OS_IRIX)
03750 XID device_id;
03751 #endif
03752
03753 if (ev->type == tablet->xinput_motion) {
03754 motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
03755 for (;;) {
03756 if (!XCheckTypedWindowEvent(X11->display, internalWinId(), MotionNotify, &mouseMotionEvent))
03757 break;
03758 if (!XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEvent)) {
03759 XPutBackEvent(X11->display, &mouseMotionEvent);
03760 break;
03761 }
03762 if (mouseMotionEvent.xmotion.time != motion->time) {
03763 XPutBackEvent(X11->display, &mouseMotionEvent);
03764 XPutBackEvent(X11->display, &xinputMotionEvent);
03765
03766 }
03767 motion = (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent));
03768 break;
03769 }
03770 t = QEvent::TabletMove;
03771 global = QPoint(motion->x_root, motion->y_root);
03772 curr = QPoint(motion->x, motion->y);
03773 #if !defined (Q_OS_IRIX)
03774 device_id = motion->deviceid;
03775 #endif
03776 } else if (ev->type == tablet->xinput_button_press || ev->type == tablet->xinput_button_release) {
03777 if (ev->type == tablet->xinput_button_press) {
03778 t = QEvent::TabletPress;
03779 } else {
03780 t = QEvent::TabletRelease;
03781 }
03782 button = (XDeviceButtonEvent*)ev;
03783
03784 global = QPoint(button->x_root, button->y_root);
03785 curr = QPoint(button->x, button->y);
03786 #if !defined (Q_OS_IRIX)
03787 device_id = button->deviceid;
03788 #endif
03789 } else {
03790 if (ev->type == tablet->xinput_proximity_in)
03791 t = QEvent::TabletEnterProximity;
03792 else
03793 t = QEvent::TabletLeaveProximity;
03794 proximity = (const XProximityNotifyEvent*)ev;
03795 #if !defined (Q_OS_IRIX)
03796 device_id = proximity->deviceid;
03797 #endif
03798 }
03799
03800 qint64 uid;
03801 QRect screenArea = qApp->desktop()->screenGeometry(this);
03802 #if defined (Q_OS_IRIX)
03803 s = XQueryDeviceState(X11->display, static_cast<XDevice *>(tablet->device));
03804 if (!s)
03805 return false;
03806 iClass = s->data;
03807 for (j = 0; j < s->num_classes; j++) {
03808 if (iClass->c_class == ValuatorClass) {
03809 vs = reinterpret_cast<XValuatorState *>(iClass);
03810
03811 if (vs->valuators[WAC_TRANSDUCER_I]
03812 & WAC_TRANSDUCER_PROX_MSK) {
03813 switch (vs->valuators[WAC_TRANSDUCER_I]
03814 & WAC_TRANSDUCER_MSK) {
03815 case WAC_PUCK_ID:
03816 pointerType = QTabletEvent::Puck;
03817 break;
03818 case WAC_STYLUS_ID:
03819 pointerType = QTabletEvent::Pen;
03820 break;
03821 case WAC_ERASER_ID:
03822 pointerType = QTabletEvent::Eraser;
03823 break;
03824 }
03825
03826 uid = vs->valuators[WAC_TRANSDUCER_I] & WAC_TRANSDUCER_ID_MSK;
03827 uid = (uid << 24) | vs->valuators[WAC_SERIAL_NUM_I];
03828 switch (WAC_TRANSDUCER_I & 0x0F0600) {
03829 case 0x080200:
03830 deviceType = QTabletEvent::Stylus;
03831 break;
03832 case 0x090200:
03833 deviceType = QTabletEvent::Airbrush;
03834 break;
03835 case 0x000400:
03836 deviceType = QTabletEvent::FourDMouse;
03837 break;
03838 case 0x000600:
03839 deviceType = QTabletEvent::Puck;
03840 break;
03841 case 0x080400:
03842 deviceType = QTabletEvent::RotationStylus;
03843 break;
03844 }
03845 } else {
03846 pointerType = QTabletEvent::UnknownPointer;
03847 deviceType = QTabletEvent::NoDevice;
03848 uid = 0;
03849 }
03850
03851 if (!proximity) {
03852
03853 xTilt = short(vs->valuators[WAC_XTILT_I]);
03854 yTilt = short(vs->valuators[WAC_YTILT_I]);
03855 pressure = vs->valuators[WAC_PRESSURE_I];
03856 if (deviceType == QTabletEvent::FourDMouse
03857 || deviceType == QTabletEvent::RotationStylus) {
03858 rotation = vs->valuators[WAC_ROTATION_I] / 64.0;
03859 if (deviceType == QTabletEvent::FourDMouse)
03860 z = vs->valuators[WAC_ZCOORD_I];
03861 } else if (deviceType == QTabletEvent::Airbrush) {
03862 tangentialPressure = vs->valuators[WAC_TAN_PRESSURE_I]
03863 / qreal(tablet->maxTanPressure - tablet->minTanPressure);
03864 }
03865
03866 hiRes = tablet->scaleCoord(vs->valuators[WAC_XCOORD_I], vs->valuators[WAC_YCOORD_I],
03867 screenArea.x(), screenArea.width(),
03868 screenArea.y(), screenArea.height());
03869 }
03870 break;
03871 }
03872 iClass = reinterpret_cast<XInputClass*>(reinterpret_cast<char*>(iClass) + iClass->length);
03873 }
03874 XFreeDeviceState(s);
03875 #else
03876 QTabletDeviceDataList *tablet_list = qt_tablet_devices();
03877 for (int i = 0; i < tablet_list->size(); ++i) {
03878 const QTabletDeviceData &t = tablet_list->at(i);
03879 if (device_id == static_cast<XDevice *>(t.device)->device_id) {
03880 deviceType = t.deviceType;
03881 if (deviceType == QTabletEvent::XFreeEraser) {
03882 deviceType = QTabletEvent::Stylus;
03883 pointerType = QTabletEvent::Eraser;
03884 } else if (deviceType == QTabletEvent::Stylus) {
03885 pointerType = QTabletEvent::Pen;
03886 }
03887
03888 break;
03889 }
03890 }
03891
03892 uint hibyte1 = 0;
03893 uint hibyte2 = 0;
03894 uint hibyte3 = 0;
03895 if (motion) {
03896 hibyte1 = (motion->axis_data[3] & 0xffff0000) >> 16;
03897 hibyte2 = (motion->axis_data[4] & 0xffff0000) >> 16;
03898 hibyte3 = (motion->axis_data[5] & 0xffff0000) >> 16;
03899 xTilt = short(motion->axis_data[3] & 0xffff);
03900 yTilt = short(motion->axis_data[4] & 0xffff);
03901 pressure = motion->axis_data[2];
03902 modifiers = X11->translateModifiers(motion->state);
03903 hiRes = tablet->scaleCoord(motion->axis_data[0], motion->axis_data[1],
03904 screenArea.x(), screenArea.width(),
03905 screenArea.y(), screenArea.height());
03906 } else if (button) {
03907 hibyte1 = (button->axis_data[3] & 0xffff0000) >> 16;
03908 hibyte2 = (button->axis_data[4] & 0xffff0000) >> 16;
03909 hibyte3 = (button->axis_data[5] & 0xffff0000) >> 16;
03910 xTilt = short(button->axis_data[3] & 0xffff);
03911 yTilt = short(button->axis_data[4] & 0xffff);
03912 pressure = button->axis_data[2];
03913 hiRes = tablet->scaleCoord(button->axis_data[0], button->axis_data[1],
03914 screenArea.x(), screenArea.width(),
03915 screenArea.y(), screenArea.height());
03916 modifiers = X11->translateModifiers(button->state);
03917 } else if (proximity) {
03918 hibyte1 = (proximity->axis_data[3] & 0xffff0000) >> 16;
03919 hibyte2 = (proximity->axis_data[4] & 0xffff0000) >> 16;
03920 hibyte3 = (proximity->axis_data[5] & 0xffff0000) >> 16;
03921 pressure = 0;
03922 modifiers = 0;
03923 }
03924
03925
03926 if (hibyte1 == 0 || hibyte1 == 0xffff) {
03927 uid = -1;
03928 } else {
03929 uid = hibyte1 & 0x0f06;
03930 uid = (uid << 24) | ((hibyte2 << 16) | hibyte3);
03931 }
03932 #endif
03933 QTabletEvent e(t, curr, global, hiRes,
03934 deviceType, pointerType,
03935 qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
03936 xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
03937 if (proximity)
03938 QApplication::sendSpontaneousEvent(qApp, &e);
03939 else
03940 QApplication::sendSpontaneousEvent(w, &e);
03941 return true;
03942 }
03943 #endif
03944
03945 bool QETWidget::translatePropertyEvent(const XEvent *event)
03946 {
03947 Q_D(QWidget);
03948 if (!isWindow()) return true;
03949
03950 Atom ret;
03951 int format, e;
03952 unsigned char *data = 0;
03953 unsigned long nitems, after;
03954
03955 if (event->xproperty.atom == ATOM(_KDE_NET_WM_FRAME_STRUT)) {
03956 QTLWExtra *topData = d->topData();
03957 topData->frameStrut.setCoords(0, 0, 0, 0);
03958 this->data->fstrut_dirty = 1;
03959
03960 if (event->xproperty.state == PropertyNewValue) {
03961 e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_KDE_NET_WM_FRAME_STRUT),
03962 0, 4,
03963 False, XA_CARDINAL, &ret, &format, &nitems, &after, &data);
03964
03965 if (e == Success && ret == XA_CARDINAL &&
03966 format == 32 && nitems == 4) {
03967 long *strut = (long *) data;
03968 topData->frameStrut.setCoords(strut[0], strut[1], strut[2], strut[3]);
03969 this->data->fstrut_dirty = 0;
03970 }
03971 }
03972 } else if (event->xproperty.atom == ATOM(_NET_WM_STATE)) {
03973 bool max = false;
03974 bool full = false;
03975 Qt::WindowStates oldState = Qt::WindowStates(this->data->window_state);
03976
03977 if (event->xproperty.state == PropertyNewValue) {
03978
03979
03980 e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_NET_WM_STATE), 0, 1024,
03981 False, XA_ATOM, &ret, &format, &nitems, &after, &data);
03982
03983 if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) {
03984 Atom *states = (Atom *) data;
03985
03986 unsigned long i;
03987 for (i = 0; i < nitems; i++) {
03988 if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_VERT)
03989 || states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
03990 max = true;
03991 else if (states[i] == ATOM(_NET_WM_STATE_FULLSCREEN))
03992 full = true;
03993 }
03994 }
03995 }
03996
03997 bool send_event = false;
03998
03999 if (qt_net_supports(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
04000 && qt_net_supports(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))) {
04001 if (max && !isMaximized()) {
04002 this->data->window_state = this->data->window_state | Qt::WindowMaximized;
04003 send_event = true;
04004 } else if (!max && isMaximized()) {
04005 this->data->window_state &= !Qt::WindowMaximized;
04006 send_event = true;
04007 }
04008 }
04009
04010 if (qt_net_supports(ATOM(_NET_WM_STATE_FULLSCREEN))) {
04011 if (full && !isFullScreen()) {
04012 this->data->window_state = this->data->window_state | Qt::WindowFullScreen;
04013 send_event = true;
04014 } else if (!full && isFullScreen()) {
04015 this->data->window_state &= ~Qt::WindowFullScreen;
04016 send_event = true;
04017 }
04018 }
04019
04020 if (send_event) {
04021 QWindowStateChangeEvent e(oldState);
04022 QApplication::sendSpontaneousEvent(this, &e);
04023 }
04024 } else if (event->xproperty.atom == ATOM(WM_STATE)) {
04025
04026 d->topData()->frameStrut.setCoords(0, 0, 0, 0);
04027 this->data->fstrut_dirty = 1;
04028
04029 if (event->xproperty.state == PropertyDelete) {
04030
04031
04032
04033 d->topData()->parentWinId = 0;
04034 d->topData()->validWMState = 0;
04035
04036
04037 if (X11->deferred_map.removeAll(this)) {
04038 XMapWindow(X11->display, internalWinId());
04039 } else if (isVisible() && !testAttribute(Qt::WA_Mapped)) {
04040
04041
04042
04043
04044
04045 setAttribute(Qt::WA_WState_ExplicitShowHide, false);
04046 setAttribute(Qt::WA_WState_Visible, false);
04047 }
04048 } else {
04049
04050
04051
04052 e = XGetWindowProperty(X11->display, internalWinId(), ATOM(WM_STATE), 0, 2, False,
04053 ATOM(WM_STATE), &ret, &format, &nitems, &after, &data);
04054
04055 if (e == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
04056 long *state = (long *) data;
04057 switch (state[0]) {
04058 case WithdrawnState:
04059
04060
04061
04062 XDeleteProperty(X11->display, internalWinId(), ATOM(WM_STATE));
04063
04064
04065
04066 d->topData()->parentWinId = 0;
04067 d->topData()->validWMState = 0;
04068
04069
04070 if (X11->deferred_map.removeAll(this)) {
04071 XMapWindow(X11->display, internalWinId());
04072 } else if (isVisible() && !testAttribute(Qt::WA_Mapped)) {
04073
04074
04075
04076
04077
04078
04079 setAttribute(Qt::WA_WState_ExplicitShowHide, false);
04080 setAttribute(Qt::WA_WState_Visible, false);
04081 }
04082 break;
04083
04084 case IconicState:
04085 d->topData()->validWMState = 1;
04086 if (!isMinimized()) {
04087
04088 this->data->window_state = this->data->window_state | Qt::WindowMinimized;
04089 QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state & ~Qt::WindowMinimized));
04090 QApplication::sendSpontaneousEvent(this, &e);
04091 }
04092 break;
04093
04094 default:
04095 d->topData()->validWMState = 1;
04096 if (isMinimized()) {
04097
04098 this->data->window_state &= ~Qt::WindowMinimized;
04099 QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state | Qt::WindowMinimized));
04100 QApplication::sendSpontaneousEvent(this, &e);
04101 }
04102 break;
04103 }
04104 }
04105 }
04106 } else if (event->xproperty.atom == ATOM(_NET_WM_WINDOW_OPACITY)) {
04107
04108 if (event->xproperty.state == PropertyNewValue) {
04109 e = XGetWindowProperty(event->xclient.display,
04110 event->xclient.window,
04111 ATOM(_NET_WM_WINDOW_OPACITY),
04112 0, 1, False, XA_CARDINAL,
04113 &ret, &format, &nitems, &after, &data);
04114
04115 if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 1
04116 && after == 0 && data) {
04117 ulong value = *(ulong*)(data);
04118 d->topData()->opacity = uint(value >> 24);
04119 }
04120 } else
04121 d->topData()->opacity = 255;
04122 }
04123
04124 if (data)
04125 XFree(data);
04126
04127 return true;
04128 }
04129
04130
04131
04132
04133
04134
04135
04136 struct PaintEventInfo {
04137 Window window;
04138 };
04139
04140 #if defined(Q_C_CALLBACKS)
04141 extern "C" {
04142 #endif
04143
04144 static Bool isPaintOrScrollDoneEvent(Display *, XEvent *ev, XPointer a)
04145 {
04146 PaintEventInfo *info = (PaintEventInfo *)a;
04147 if (ev->type == Expose || ev->type == GraphicsExpose
04148 || ev->type == ClientMessage
04149 && ev->xclient.message_type == ATOM(_QT_SCROLL_DONE))
04150 {
04151 if (ev->xexpose.window == info->window)
04152 return True;
04153 }
04154 return False;
04155 }
04156
04157 #if defined(Q_C_CALLBACKS)
04158 }
04159 #endif
04160
04161
04162
04163 static
04164 bool translateBySips(QWidget* that, QRect& paintRect)
04165 {
04166 int dx=0, dy=0;
04167 int sips=0;
04168 for (int i = 0; i < X11->sip_list.size(); ++i) {
04169 const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
04170 if (sip.scrolled_widget == that) {
04171 if (sips) {
04172 dx += sip.dx;
04173 dy += sip.dy;
04174 }
04175 sips++;
04176 }
04177 }
04178 if (sips > 1) {
04179 paintRect.translate(dx, dy);
04180 return true;
04181 }
04182 return false;
04183 }
04184
04185 bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
04186 {
04187 return QCoreApplication::sendSpontaneousEvent(receiver, event);
04188 }
04189
04190 void QETWidget::translatePaintEvent(const XEvent *event)
04191 {
04192 Q_D(QWidget);
04193 QRect paintRect(event->xexpose.x, event->xexpose.y,
04194 event->xexpose.width, event->xexpose.height);
04195 XEvent xevent;
04196 PaintEventInfo info;
04197 info.window = internalWinId();
04198 translateBySips(this, paintRect);
04199 paintRect = d->mapFromWS(paintRect);
04200
04201 QRegion paintRegion = paintRect;
04202
04203
04204 while (XCheckIfEvent(X11->display,&xevent,isPaintOrScrollDoneEvent,
04205 (XPointer)&info) &&
04206 !qt_x11EventFilter(&xevent) &&
04207 !x11Event(&xevent))
04208 {
04209 if (xevent.type == Expose || xevent.type == GraphicsExpose) {
04210 QRect exposure(xevent.xexpose.x,
04211 xevent.xexpose.y,
04212 xevent.xexpose.width,
04213 xevent.xexpose.height);
04214 translateBySips(this, exposure);
04215 exposure = d->mapFromWS(exposure);
04216 paintRegion |= exposure;
04217 } else {
04218 translateScrollDoneEvent(&xevent);
04219 }
04220 }
04221
04222 if (!paintRegion.isEmpty() && !(!testAttribute(Qt::WA_StaticContents) && testAttribute(Qt::WA_WState_ConfigPending))) {
04223 extern void qt_syncBackingStore(QRegion rgn, QWidget *widget);
04224 qt_syncBackingStore(paintRegion, this);
04225 }
04226 }
04227
04228
04229
04230
04231
04232 bool QETWidget::translateScrollDoneEvent(const XEvent *event)
04233 {
04234 long id = event->xclient.data.l[0];
04235
04236
04237 for (int i = 0; i < X11->sip_list.size(); ++i) {
04238 const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
04239 if (sip.id == id) {
04240 X11->sip_list.removeAt(i);
04241 return true;
04242 }
04243 }
04244
04245 return false;
04246 }
04247
04248
04249
04250
04251 bool QETWidget::translateConfigEvent(const XEvent *event)
04252 {
04253 Q_D(QWidget);
04254 bool wasResize = testAttribute(Qt::WA_WState_ConfigPending);
04255 setAttribute(Qt::WA_WState_ConfigPending, false);
04256
04257 if (isWindow()) {
04258 QPoint newCPos(geometry().topLeft());
04259 QSize newSize(event->xconfigure.width, event->xconfigure.height);
04260
04261 bool trust = (d->topData()->parentWinId == XNone ||
04262 d->topData()->parentWinId == QX11Info::appRootWindow());
04263
04264 if (event->xconfigure.send_event || trust) {
04265
04266
04267 newCPos.rx() = event->xconfigure.x + event->xconfigure.border_width;
04268 newCPos.ry() = event->xconfigure.y + event->xconfigure.border_width;
04269 }
04270
04271 if (isVisible())
04272 QApplication::syncX();
04273
04274 if (d->extra->compress_events) {
04275
04276 XEvent otherEvent;
04277 while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify,
04278 &otherEvent)) {
04279 if (qt_x11EventFilter(&otherEvent))
04280 continue;
04281
04282 if (x11Event(&otherEvent))
04283 continue;
04284
04285 if (otherEvent.xconfigure.event != otherEvent.xconfigure.window)
04286 continue;
04287
04288 newSize.setWidth(otherEvent.xconfigure.width);
04289 newSize.setHeight(otherEvent.xconfigure.height);
04290
04291 if (otherEvent.xconfigure.send_event || trust) {
04292 newCPos.rx() = otherEvent.xconfigure.x +
04293 otherEvent.xconfigure.border_width;
04294 newCPos.ry() = otherEvent.xconfigure.y +
04295 otherEvent.xconfigure.border_width;
04296 }
04297 }
04298 }
04299
04300 QRect cr (geometry());
04301 if (newCPos != cr.topLeft()) {
04302 QPoint oldPos = geometry().topLeft();
04303 cr.moveTopLeft(newCPos);
04304 data->crect = cr;
04305 if (isVisible()) {
04306 QMoveEvent e(newCPos, oldPos);
04307 QApplication::sendSpontaneousEvent(this, &e);
04308 } else {
04309 setAttribute(Qt::WA_PendingMoveEvent, true);
04310 }
04311 }
04312 if (newSize != cr.size()) {
04313 QSize oldSize = size();
04314 cr.setSize(newSize);
04315 data->crect = cr;
04316
04317 uint old_state = data->window_state;
04318 if (!qt_net_supports(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
04319 && !qt_net_supports(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
04320 data->window_state &= ~Qt::WindowMaximized;
04321 if (!qt_net_supports(ATOM(_NET_WM_STATE_FULLSCREEN)))
04322 data->window_state &= ~Qt::WindowFullScreen;
04323
04324 if (old_state != data->window_state) {
04325 QWindowStateChangeEvent e((Qt::WindowStates) old_state);
04326 QApplication::sendEvent(this, &e);
04327 }
04328
04329 if (isVisible()) {
04330 QResizeEvent e(newSize, oldSize);
04331 QApplication::sendSpontaneousEvent(this, &e);
04332 } else {
04333 setAttribute(Qt::WA_PendingResizeEvent, true);
04334 }
04335 wasResize = true;
04336 }
04337
04338 } else {
04339 XEvent xevent;
04340 while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
04341 !qt_x11EventFilter(&xevent) &&
04342 !x11Event(&xevent))
04343 ;
04344 }
04345
04346 if (wasResize && !testAttribute(Qt::WA_StaticContents)) {
04347 XEvent xevent;
04348 PaintEventInfo info;
04349 info.window = internalWinId();
04350 while (XCheckIfEvent(X11->display,&xevent,isPaintOrScrollDoneEvent,
04351 (XPointer)&info) &&
04352 !qt_x11EventFilter(&xevent) &&
04353 !x11Event(&xevent))
04354 ;
04355 if(QWidgetBackingStore::paintOnScreen(this)) {
04356 repaint();
04357 } else {
04358 extern void qt_syncBackingStore(QRegion rgn, QWidget *widget);
04359 qt_syncBackingStore(d->clipRect(), this);
04360 }
04361 }
04362 return true;
04363 }
04364
04365
04366
04367
04368 bool QETWidget::translateCloseEvent(const XEvent *)
04369 {
04370 Q_D(QWidget);
04371 return d->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
04372 }
04373
04374
04393 void QApplication::setCursorFlashTime(int msecs)
04394 {
04395 QApplicationPrivate::cursor_flash_time = msecs;
04396 }
04397
04398 int QApplication::cursorFlashTime()
04399 {
04400 return QApplicationPrivate::cursor_flash_time;
04401 }
04402
04415 void QApplication::setDoubleClickInterval(int ms)
04416 {
04417 QApplicationPrivate::mouse_double_click_time = ms;
04418 }
04419
04420 int QApplication::doubleClickInterval()
04421 {
04422 return QApplicationPrivate::mouse_double_click_time;
04423 }
04424
04435 void QApplication::setKeyboardInputInterval(int ms)
04436 {
04437 QApplicationPrivate::keyboard_input_time = ms;
04438 }
04439
04440 int QApplication::keyboardInputInterval()
04441 {
04442 return QApplicationPrivate::keyboard_input_time;
04443 }
04444
04445
04454 void QApplication::setWheelScrollLines(int n)
04455 {
04456 QApplicationPrivate::wheel_scroll_lines = n;
04457 }
04458
04459 int QApplication::wheelScrollLines()
04460 {
04461 return QApplicationPrivate::wheel_scroll_lines;
04462 }
04463
04473 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
04474 {
04475 switch (effect) {
04476 case Qt::UI_AnimateMenu:
04477 if (enable) QApplicationPrivate::fade_menu = false;
04478 QApplicationPrivate::animate_menu = enable;
04479 break;
04480 case Qt::UI_FadeMenu:
04481 if (enable)
04482 QApplicationPrivate::animate_menu = true;
04483 QApplicationPrivate::fade_menu = enable;
04484 break;
04485 case Qt::UI_AnimateCombo:
04486 QApplicationPrivate::animate_combo = enable;
04487 break;
04488 case Qt::UI_AnimateTooltip:
04489 if (enable) QApplicationPrivate::fade_tooltip = false;
04490 QApplicationPrivate::animate_tooltip = enable;
04491 break;
04492 case Qt::UI_FadeTooltip:
04493 if (enable)
04494 QApplicationPrivate::animate_tooltip = true;
04495 QApplicationPrivate::fade_tooltip = enable;
04496 break;
04497 case Qt::UI_AnimateToolBox:
04498 QApplicationPrivate::animate_toolbox = enable;
04499 break;
04500 default:
04501 QApplicationPrivate::animate_ui = enable;
04502 break;
04503 }
04504 }
04505
04517 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
04518 {
04519 if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
04520 return false;
04521
04522 switch(effect) {
04523 case Qt::UI_AnimateMenu:
04524 return QApplicationPrivate::animate_menu;
04525 case Qt::UI_FadeMenu:
04526 return QApplicationPrivate::fade_menu;
04527 case Qt::UI_AnimateCombo:
04528 return QApplicationPrivate::animate_combo;
04529 case Qt::UI_AnimateTooltip:
04530 return QApplicationPrivate::animate_tooltip;
04531 case Qt::UI_FadeTooltip:
04532 return QApplicationPrivate::fade_tooltip;
04533 case Qt::UI_AnimateToolBox:
04534 return QApplicationPrivate::animate_toolbox;
04535 default:
04536 return QApplicationPrivate::animate_ui;
04537 }
04538 }
04539
04540
04541
04542
04543
04544 #ifndef QT_NO_SESSIONMANAGER
04545
04546 #include <X11/SM/SMlib.h>
04547
04548 class QSessionManagerPrivate : public QObjectPrivate
04549 {
04550 public:
04551 QSessionManagerPrivate(QSessionManager* mgr, QString& id, QString& key)
04552 : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key), eventLoop(0) {}
04553 QSessionManager* sm;
04554 QStringList restartCommand;
04555 QStringList discardCommand;
04556 QString& sessionId;
04557 QString& sessionKey;
04558 QSessionManager::RestartHint restartHint;
04559 QEventLoop *eventLoop;
04560 };
04561
04562 class QSmSocketReceiver : public QObject
04563 {
04564 Q_OBJECT
04565 public:
04566 QSmSocketReceiver(int socket)
04567 {
04568 QSocketNotifier* sn = new QSocketNotifier(socket, QSocketNotifier::Read, this);
04569 connect(sn, SIGNAL(activated(int)), this, SLOT(socketActivated(int)));
04570 }
04571
04572 public slots:
04573 void socketActivated(int);
04574 };
04575
04576
04577 static SmcConn smcConnection = 0;
04578 static bool sm_interactionActive;
04579 static bool sm_smActive;
04580 static int sm_interactStyle;
04581 static int sm_saveType;
04582 static bool sm_cancel;
04583
04584 static bool sm_waitingForInteraction;
04585 static bool sm_isshutdown;
04586
04587 static bool sm_phase2;
04588 static bool sm_in_phase2;
04589
04590 static QSmSocketReceiver* sm_receiver = 0;
04591
04592 static void resetSmState();
04593 static void sm_setProperty(const char* name, const char* type,
04594 int num_vals, SmPropValue* vals);
04595 static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
04596 int saveType, Bool shutdown , int interactStyle, Bool fast);
04597 static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData) ;
04598 static void sm_dieCallback(SmcConn smcConn, SmPointer clientData) ;
04599 static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData);
04600 static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer clientData);
04601 static void sm_interactCallback(SmcConn smcConn, SmPointer clientData);
04602 static void sm_performSaveYourself(QSessionManagerPrivate*);
04603
04604 static void resetSmState()
04605 {
04606
04607 sm_waitingForInteraction = false;
04608 sm_interactionActive = false;
04609 sm_interactStyle = SmInteractStyleNone;
04610 sm_smActive = false;
04611 qt_sm_blockUserInput = false;
04612 sm_isshutdown = false;
04613
04614 sm_phase2 = false;
04615 sm_in_phase2 = false;
04616 }
04617
04618
04619
04620
04621 static void sm_setProperty(const char* name, const char* type,
04622 int num_vals, SmPropValue* vals)
04623 {
04624 if (num_vals) {
04625 SmProp prop;
04626 prop.name = (char*)name;
04627 prop.type = (char*)type;
04628 prop.num_vals = num_vals;
04629 prop.vals = vals;
04630
04631 SmProp* props[1];
04632 props[0] = ∝
04633 SmcSetProperties(smcConnection, 1, props);
04634 }
04635 else {
04636 char* names[1];
04637 names[0] = (char*) name;
04638 SmcDeleteProperties(smcConnection, 1, names);
04639 }
04640 }
04641
04642 static void sm_setProperty(const QString& name, const QString& value)
04643 {
04644 QByteArray v = value.toUtf8();
04645 SmPropValue prop;
04646 prop.length = v.length();
04647 prop.value = (SmPointer) v.constData();
04648 sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop);
04649 }
04650
04651 static void sm_setProperty(const QString& name, const QStringList& value)
04652 {
04653 SmPropValue *prop = new SmPropValue[value.count()];
04654 int count = 0;
04655 QList<QByteArray> vl;
04656 for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
04657 prop[count].length = (*it).length();
04658 vl.append((*it).toUtf8());
04659 prop[count].value = (char*)vl.last().data();
04660 ++count;
04661 }
04662 sm_setProperty(name.toLatin1().data(), SmLISTofARRAY8, count, prop);
04663 delete [] prop;
04664 }
04665
04666
04667
04668 struct QT_smcConn {
04669 unsigned int save_yourself_in_progress : 1;
04670 unsigned int shutdown_in_progress : 1;
04671 };
04672
04673 static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
04674 int saveType, Bool shutdown , int interactStyle, Bool )
04675 {
04676 if (smcConn != smcConnection)
04677 return;
04678 sm_cancel = false;
04679 sm_smActive = true;
04680 sm_isshutdown = shutdown;
04681 sm_saveType = saveType;
04682 sm_interactStyle = interactStyle;
04683
04684
04685
04686
04687 ((QT_smcConn*)smcConn)->save_yourself_in_progress = true;
04688 if (sm_isshutdown)
04689 ((QT_smcConn*)smcConn)->shutdown_in_progress = true;
04690
04691 sm_performSaveYourself((QSessionManagerPrivate*) clientData);
04692 if (!sm_isshutdown)
04693 resetSmState();
04694 }
04695
04696 static void sm_performSaveYourself(QSessionManagerPrivate* smd)
04697 {
04698 if (sm_isshutdown)
04699 qt_sm_blockUserInput = true;
04700
04701 QSessionManager* sm = smd->sm;
04702
04703
04704 timeval tv;
04705 gettimeofday(&tv, 0);
04706 smd->sessionKey = QString::number(qulonglong(tv.tv_sec)) + QLatin1Char('_') + QString::number(qulonglong(tv.tv_usec));
04707
04708 QStringList arguments = qApp->arguments();
04709 QString argument0 = arguments.isEmpty() ? qApp->applicationFilePath() : arguments.at(0);
04710
04711
04712 sm_setProperty(QString::fromLatin1(SmProgram), argument0);
04713
04714 struct passwd *entryPtr = 0;
04715 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
04716 QVarLengthArray<char, 1024> buf(sysconf(_SC_GETPW_R_SIZE_MAX));
04717 struct passwd entry;
04718 getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr);
04719 #else
04720 entryPtr = getpwuid(geteuid());
04721 #endif
04722 if (entryPtr)
04723 sm_setProperty(QString::fromLatin1(SmUserID), QString::fromLatin1(entryPtr->pw_name));
04724
04725
04726 QStringList restart;
04727 restart << argument0 << QLatin1String("-session")
04728 << smd->sessionId + QLatin1Char('_') + smd->sessionKey;
04729 if (qstricmp(appName, QX11Info::appClass()) != 0)
04730 restart << QLatin1String("-name") << qAppName();
04731 sm->setRestartCommand(restart);
04732 QStringList discard;
04733 sm->setDiscardCommand(discard);
04734
04735 switch (sm_saveType) {
04736 case SmSaveBoth:
04737 qApp->commitData(*sm);
04738 if (sm_isshutdown && sm_cancel)
04739 break;
04740
04741 case SmSaveLocal:
04742 qApp->saveState(*sm);
04743 break;
04744 case SmSaveGlobal:
04745 qApp->commitData(*sm);
04746 break;
04747 default:
04748 break;
04749 }
04750
04751 if (sm_phase2 && !sm_in_phase2) {
04752 SmcRequestSaveYourselfPhase2(smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd);
04753 qt_sm_blockUserInput = false;
04754 }
04755 else {
04756
04757
04758
04759 if (sm_interactionActive) {
04760 SmcInteractDone(smcConnection, sm_isshutdown && sm_cancel);
04761 sm_interactionActive = false;
04762 }
04763 else if (sm_cancel && sm_isshutdown) {
04764 if (sm->allowsErrorInteraction()) {
04765 SmcInteractDone(smcConnection, True);
04766 sm_interactionActive = false;
04767 }
04768 }
04769
04770
04771 sm_setProperty(QString::fromLatin1(SmRestartCommand), sm->restartCommand());
04772 sm_setProperty(QString::fromLatin1(SmDiscardCommand), sm->discardCommand());
04773
04774
04775 SmPropValue prop;
04776 prop.length = sizeof(int);
04777 int value = sm->restartHint();
04778 prop.value = (SmPointer) &value;
04779 sm_setProperty(SmRestartStyleHint, SmCARD8, 1, &prop);
04780
04781
04782 SmcSaveYourselfDone(smcConnection, !sm_cancel);
04783 }
04784 }
04785
04786 static void sm_dieCallback(SmcConn smcConn, SmPointer )
04787 {
04788 if (smcConn != smcConnection)
04789 return;
04790 resetSmState();
04791 QEvent quitEvent(QEvent::Quit);
04792 QApplication::sendEvent(qApp, &quitEvent);
04793 }
04794
04795 static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)
04796 {
04797 if (smcConn != smcConnection)
04798 return;
04799 if (sm_waitingForInteraction)
04800 ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
04801 resetSmState();
04802 }
04803
04804 static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer )
04805 {
04806 if (smcConn != smcConnection)
04807 return;
04808 resetSmState();
04809 }
04810
04811 static void sm_interactCallback(SmcConn smcConn, SmPointer clientData)
04812 {
04813 if (smcConn != smcConnection)
04814 return;
04815 if (sm_waitingForInteraction)
04816 ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
04817 }
04818
04819 static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
04820 {
04821 if (smcConn != smcConnection)
04822 return;
04823 sm_in_phase2 = true;
04824 sm_performSaveYourself((QSessionManagerPrivate*) clientData);
04825 }
04826
04827
04828 void QSmSocketReceiver::socketActivated(int)
04829 {
04830 IceProcessMessages(SmcGetIceConnection(smcConnection), 0, 0);
04831 }
04832
04833
04834 #undef Bool
04835 #include "qapplication_x11.moc"
04836
04837 QSessionManager::QSessionManager(QApplication * app, QString &id, QString& key)
04838 : QObject(*new QSessionManagerPrivate(this, id, key), app)
04839 {
04840 Q_D(QSessionManager);
04841 d->restartHint = RestartIfRunning;
04842
04843 resetSmState();
04844 char cerror[256];
04845 char* myId = 0;
04846 QByteArray b_id = id.toLatin1();
04847 char* prevId = b_id.data();
04848
04849 SmcCallbacks cb;
04850 cb.save_yourself.callback = sm_saveYourselfCallback;
04851 cb.save_yourself.client_data = (SmPointer) d;
04852 cb.die.callback = sm_dieCallback;
04853 cb.die.client_data = (SmPointer) d;
04854 cb.save_complete.callback = sm_saveCompleteCallback;
04855 cb.save_complete.client_data = (SmPointer) d;
04856 cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
04857 cb.shutdown_cancelled.client_data = (SmPointer) d;
04858
04859
04860 if (qgetenv("SESSION_MANAGER").isEmpty())
04861 return;
04862
04863 smcConnection = SmcOpenConnection(0, 0, 1, 0,
04864 SmcSaveYourselfProcMask |
04865 SmcDieProcMask |
04866 SmcSaveCompleteProcMask |
04867 SmcShutdownCancelledProcMask,
04868 &cb,
04869 prevId,
04870 &myId,
04871 256, cerror);
04872
04873 id = QString::fromLatin1(myId);
04874 ::free(myId);
04875
04876 QString error = QString::fromLocal8Bit(cerror);
04877 if (!smcConnection) {
04878 qWarning("Qt: Session management error: %s", qPrintable(error));
04879 }
04880 else {
04881 sm_receiver = new QSmSocketReceiver(IceConnectionNumber(SmcGetIceConnection(smcConnection)));
04882 }
04883 }
04884
04885 QSessionManager::~QSessionManager()
04886 {
04887 if (smcConnection)
04888 SmcCloseConnection(smcConnection, 0, 0);
04889 smcConnection = 0;
04890 delete sm_receiver;
04891 }
04892
04893 QString QSessionManager::sessionId() const
04894 {
04895 Q_D(const QSessionManager);
04896 return d->sessionId;
04897 }
04898
04899 QString QSessionManager::sessionKey() const
04900 {
04901 Q_D(const QSessionManager);
04902 return d->sessionKey;
04903 }
04904
04905
04906 void* QSessionManager::handle() const
04907 {
04908 return (void*) smcConnection;
04909 }
04910
04911
04912 bool QSessionManager::allowsInteraction()
04913 {
04914 Q_D(QSessionManager);
04915 if (sm_interactionActive)
04916 return true;
04917
04918 if (sm_waitingForInteraction)
04919 return false;
04920
04921 if (sm_interactStyle == SmInteractStyleAny) {
04922 sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogNormal,
04923 sm_interactCallback, (SmPointer*) d);
04924 }
04925 if (sm_waitingForInteraction) {
04926 QEventLoop eventLoop;
04927 d->eventLoop = &eventLoop;
04928 (void) eventLoop.exec();
04929 d->eventLoop = 0;
04930
04931 sm_waitingForInteraction = false;
04932 if (sm_smActive) {
04933 sm_interactionActive = true;
04934 qt_sm_blockUserInput = false;
04935 return true;
04936 }
04937 }
04938 return false;
04939 }
04940
04941 bool QSessionManager::allowsErrorInteraction()
04942 {
04943 Q_D(QSessionManager);
04944 if (sm_interactionActive)
04945 return true;
04946
04947 if (sm_waitingForInteraction)
04948 return false;
04949
04950 if (sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors) {
04951 sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogError,
04952 sm_interactCallback, (SmPointer*) d);
04953 }
04954 if (sm_waitingForInteraction) {
04955 QEventLoop eventLoop;
04956 d->eventLoop = &eventLoop;
04957 (void) eventLoop.exec();
04958 d->eventLoop = 0;
04959
04960 sm_waitingForInteraction = false;
04961 if (sm_smActive) {
04962 sm_interactionActive = true;
04963 qt_sm_blockUserInput = false;
04964 return true;
04965 }
04966 }
04967 return false;
04968 }
04969
04970 void QSessionManager::release()
04971 {
04972 if (sm_interactionActive) {
04973 SmcInteractDone(smcConnection, False);
04974 sm_interactionActive = false;
04975 if (sm_smActive && sm_isshutdown)
04976 qt_sm_blockUserInput = true;
04977 }
04978 }
04979
04980 void QSessionManager::cancel()
04981 {
04982 sm_cancel = true;
04983 }
04984
04985 void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
04986 {
04987 Q_D(QSessionManager);
04988 d->restartHint = hint;
04989 }
04990
04991 QSessionManager::RestartHint QSessionManager::restartHint() const
04992 {
04993 Q_D(const QSessionManager);
04994 return d->restartHint;
04995 }
04996
04997 void QSessionManager::setRestartCommand(const QStringList& command)
04998 {
04999 Q_D(QSessionManager);
05000 d->restartCommand = command;
05001 }
05002
05003 QStringList QSessionManager::restartCommand() const
05004 {
05005 Q_D(const QSessionManager);
05006 return d->restartCommand;
05007 }
05008
05009 void QSessionManager::setDiscardCommand(const QStringList& command)
05010 {
05011 Q_D(QSessionManager);
05012 d->discardCommand = command;
05013 }
05014
05015 QStringList QSessionManager::discardCommand() const
05016 {
05017 Q_D(const QSessionManager);
05018 return d->discardCommand;
05019 }
05020
05021 void QSessionManager::setManagerProperty(const QString& name, const QString& value)
05022 {
05023 sm_setProperty(name, value);
05024 }
05025
05026 void QSessionManager::setManagerProperty(const QString& name, const QStringList& value)
05027 {
05028 sm_setProperty(name, value);
05029 }
05030
05031 bool QSessionManager::isPhase2() const
05032 {
05033 return sm_in_phase2;
05034 }
05035
05036 void QSessionManager::requestPhase2()
05037 {
05038 sm_phase2 = true;
05039 }
05040
05041 #endif // QT_NO_SESSIONMANAGER