File indexing completed on 2024-07-14 04:51:47

0001 /***************************************************************************
0002                                    main.cpp
0003                              -------------------
0004     begin                : Sat Dec  8 03:23:02 CET 2001
0005     copyright            : (C) 2001-2003 by Tim Jansen
0006     email                : tim@tjansen.de
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "mainwindow.h"
0019 #include "trayicon.h"
0020 #include "invitationsrfbserver.h"
0021 #include "krfbconfig.h"
0022 #include "krfb_version.h"
0023 #include "krfbdebug.h"
0024 
0025 #include <KAboutData>
0026 #include <KDBusService>
0027 #include <KLocalizedString>
0028 #include <KMessageBox>
0029 #include <KWindowSystem>
0030 
0031 #include <QPixmap>
0032 #include <qwindowdefs.h>
0033 #include <QtGui/private/qtx11extras_p.h>
0034 
0035 #include <csignal>
0036 #include <X11/extensions/XTest.h>
0037 #include <QCommandLineParser>
0038 #include <QCommandLineOption>
0039 
0040 
0041 static bool checkX11Capabilities()
0042 {
0043     int bp1, bp2, majorv, minorv;
0044     Bool r = XTestQueryExtension(QX11Info::display(), &bp1, &bp2,
0045                                  &majorv, &minorv);
0046 
0047     if ((!r) || (((majorv * 1000) + minorv) < 2002)) {
0048         KMessageBox::error(nullptr,
0049                            i18n("Your X11 Server does not support the required XTest extension "
0050                                 "version 2.2. Sharing your desktop is not possible."),
0051                            i18n("Desktop Sharing Error"));
0052         return false;
0053     }
0054 
0055     return true;
0056 }
0057 
0058 static void checkOldX11PluginConfig() {
0059     if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) {
0060         qCDebug(KRFB) << "Detected deprecated configuration: preferredFrameBufferPlugin = x11";
0061         KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
0062                     QStringLiteral("preferredFrameBufferPlugin"));
0063         if (config_item) {
0064             config_item->setProperty(QStringLiteral("xcb"));
0065             KrfbConfig::self()->save();
0066             qCDebug(KRFB) << "  Fixed preferredFrameBufferPlugin from x11 to xcb.";
0067         }
0068     }
0069 }
0070 
0071 static void checkWaylandPluginConfig()
0072 {
0073     if (KrfbConfig::preferredFrameBufferPlugin() != QStringLiteral("pw")) {
0074         qWarning() << "Wayland: Detected invalid configuration: "
0075                     "preferredFrameBufferPlugin is not pipewire: "
0076                    << KrfbConfig::preferredFrameBufferPlugin();
0077         KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
0078                     QStringLiteral("preferredFrameBufferPlugin"));
0079         if (config_item) {
0080             config_item->setProperty(QStringLiteral("pw"));
0081             KrfbConfig::self()->save();
0082             qCDebug(KRFB) << "Wayland: Fixed preferredFrameBufferPlugin to \"pw\".";
0083         }
0084     }
0085 }
0086 
0087 int main(int argc, char *argv[])
0088 {
0089     QApplication app(argc, argv);
0090 
0091     KLocalizedString::setApplicationDomain("krfb");
0092 
0093     KAboutData aboutData(QStringLiteral("krfb"),
0094                          i18n("Desktop Sharing"),
0095                          QStringLiteral(KRFB_VERSION_STRING),
0096                          i18n("VNC-compatible server to share desktops"),
0097                          KAboutLicense::GPL,
0098                          i18n("(c) 2009-2010, Collabora Ltd.\n"
0099                                "(c) 2007, Alessandro Praduroux\n"
0100                                "(c) 2001-2003, Tim Jansen\n"
0101                                "(c) 2001, Johannes E. Schindelin\n"
0102                                "(c) 2000-2001, Const Kaplinsky\n"
0103                                "(c) 2000, Tridia Corporation\n"
0104                                "(c) 1999, AT&T Laboratories Boston\n"));
0105     aboutData.addAuthor(i18n("George Goldberg"),
0106                         i18n("Telepathy tubes support"),
0107                         QStringLiteral("george.goldberg@collabora.co.uk"));
0108     aboutData.addAuthor(i18n("George Kiagiadakis"),
0109                         QString(),
0110                         QStringLiteral("george.kiagiadakis@collabora.co.uk"));
0111     aboutData.addAuthor(i18n("Alessandro Praduroux"), i18n("KDE4 porting"), QStringLiteral("pradu@pradu.it"));
0112     aboutData.addAuthor(i18n("Tim Jansen"), i18n("Original author"), QStringLiteral("tim@tjansen.de"));
0113     aboutData.addCredit(i18n("Johannes E. Schindelin"),
0114                         i18n("libvncserver"));
0115     aboutData.addCredit(i18n("Const Kaplinsky"),
0116                         i18n("TightVNC encoder"));
0117     aboutData.addCredit(i18n("Tridia Corporation"),
0118                         i18n("ZLib encoder"));
0119     aboutData.addCredit(i18n("AT&T Laboratories Boston"),
0120                         i18n("original VNC encoders and "
0121                               "protocol design"));
0122     KAboutData::setApplicationData(aboutData);
0123 
0124     QCommandLineParser parser;
0125     aboutData.setupCommandLine(&parser);
0126     const QCommandLineOption nodialogOption(QStringList{ QStringLiteral("nodialog") }, i18n("Do not show the invitations management dialog at startup"));
0127     parser.addOption(nodialogOption);
0128 
0129     parser.process(app);
0130     aboutData.processCommandLine(&parser);
0131 
0132     KDBusService service(KDBusService::Unique, &app);
0133 
0134     app.setQuitOnLastWindowClosed(false);
0135 
0136     if (KWindowSystem::isPlatformX11()) {
0137         if (!checkX11Capabilities()) {
0138             return 1;
0139         }
0140 
0141         // upgrade the configuration
0142         checkOldX11PluginConfig();
0143     } else if (KWindowSystem::isPlatformWayland()) {
0144         // check that default plugin in Wayland is PipeWire
0145         checkWaylandPluginConfig();
0146     } else {
0147         KMessageBox::error(nullptr,
0148                            i18n("Desktop Sharing is not running under an X11 Server or Wayland.\n"
0149                                 "Other display servers are currently not supported."),
0150                            i18n("Desktop Sharing Error"));
0151         return 1;
0152     }
0153 
0154     //init the core
0155     InvitationsRfbServer::init();
0156 
0157     //init the GUI
0158     MainWindow mainWindow;
0159     TrayIcon trayicon(&mainWindow);
0160 
0161     QObject::connect(&service, &KDBusService::activateRequested, &mainWindow, [&mainWindow](const QStringList & /*arguments*/, const QString & /*workdir*/) {
0162         if (!mainWindow.isVisible()) {
0163             mainWindow.setVisible(true);
0164         } else {
0165             KWindowSystem::updateStartupId(mainWindow.windowHandle());
0166             KWindowSystem::activateWindow(mainWindow.windowHandle());
0167         }
0168     });
0169 
0170     if (KrfbConfig::startMinimized()) {
0171       mainWindow.hide();
0172     } else if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) {
0173         mainWindow.restore(1, false);
0174     } else if (!parser.isSet(nodialogOption)) {
0175         mainWindow.show();
0176     }
0177 
0178     sigset_t sigs;
0179     sigemptyset(&sigs);
0180     sigaddset(&sigs, SIGPIPE);
0181     sigprocmask(SIG_BLOCK, &sigs, nullptr);
0182 
0183     return app.exec();
0184 }