diff options
Diffstat (limited to 'kcontrol/info/info.cpp')
-rw-r--r-- | kcontrol/info/info.cpp | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/kcontrol/info/info.cpp b/kcontrol/info/info.cpp new file mode 100644 index 000000000..ea74ed9ac --- /dev/null +++ b/kcontrol/info/info.cpp @@ -0,0 +1,495 @@ +/* + Main Widget for showing system-dependent information. + (But all functions in THIS FILE should be system independent !) + + (C) 1998-2003 by Helge Deller <deller@kde.org> + + ** main.cpp includes this file ! ** + + This source-file includes another system-dependet sourcefile called + info_<systemname>.cpp + which should define one or more of the following defines to + indicate, that this information is really available. + + #define INFO_CPU_AVAILABLE + #define INFO_IRQ_AVAILABLE + #define INFO_DMA_AVAILABLE + #define INFO_PCI_AVAILABLE + #define INFO_IOPORTS_AVAILABLE + #define INFO_SOUND_AVAILABLE + #define INFO_DEVICES_AVAILABLE + #define INFO_SCSI_AVAILABLE + #define INFO_PARTITIONS_AVAILABLE + #define INFO_XSERVER_AVAILABLE + + right now, there is the problem, that also the .desktop-files should + depend on the systemname, so that only available .desktop-files will + be copied to kde/applnk/Settings/Information !! +*/ + +#include <qheader.h> +#include <qwhatsthis.h> +#include <qlayout.h> + +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <kdialog.h> + +#include "info.h" /* include the forward declares... */ + +#include <X11/Xlib.h> + +/* All Functions GetInfo_xyz() can set GetInfo_ErrorString, when a special + error-message should be shown to the user.... + If GetInfo_ErrorString is not modified in the function, the default string + DEFAULT_ERRORSTRING will be used... +*/ + +static QString *GetInfo_ErrorString; /* should always point to: + KInfoListWidget::ErrorString */ +static bool sorting_allowed; /* is sorting allowed by user ? */ + + + +#if defined(__linux__) +# define DEFAULT_ERRORSTRING QString::null /* i18n("Maybe the proc-filesystem is not enabled in Linux-Kernel.") */ +#elif defined(__hpux) +# define DEFAULT_ERRORSTRING QString::null +#else +#define DEFAULT_ERRORSTRING i18n("Maybe this system is not completely supported yet :-(") +#endif + + + + + +/* easier to read with such a define ! */ +#define I18N_MAX(txt,in,fm,maxw) \ + { int n = fm.width(txt=in); if (n>maxw) maxw=n; } + +#define PIXEL_ADD 20 // add x Pixel to multicolumns.. + +#define HEXDIGITS (sizeof(int)*8/4) /* 4 Bytes = 32 Bits = 8 Hex-Digits */ + +static const QString Value( int val, int numbers=1 ) +{ + return KGlobal::locale()->formatNumber(val, 0).rightJustify(numbers); +} + +static const QString HexStr(unsigned long val, int digits ) +{ + QString hexstr; + int i; + hexstr = QString::fromLatin1("0x%1").arg(val, digits, 16/*=HEX*/); + for (i=hexstr.length()-1; i>0; --i) + if (hexstr[i]==' ') + hexstr[i] = '0'; + return hexstr; +} + +static struct _event_table { + const char *name; + long value; +} event_table[] = { + { "KeyPressMask", KeyPressMask }, + { "KeyReleaseMask", KeyReleaseMask }, + { "ButtonPressMask", ButtonPressMask }, + { "ButtonReleaseMask", ButtonReleaseMask }, + { "EnterWindowMask", EnterWindowMask }, + { "LeaveWindowMask", LeaveWindowMask }, + { "PointerMotionMask", PointerMotionMask }, + { "PointerMotionHintMask", PointerMotionHintMask }, + { "Button1MotionMask", Button1MotionMask }, + { "Button2MotionMask", Button2MotionMask }, + { "Button3MotionMask", Button3MotionMask }, + { "Button4MotionMask", Button4MotionMask }, + { "Button5MotionMask", Button5MotionMask }, + { "ButtonMotionMask", ButtonMotionMask }, + { "KeymapStateMask", KeymapStateMask }, + { "ExposureMask", ExposureMask }, + { "VisibilityChangeMask", VisibilityChangeMask }, + { "StructureNotifyMask", StructureNotifyMask }, + { "ResizeRedirectMask", ResizeRedirectMask }, + { "SubstructureNotifyMask", SubstructureNotifyMask }, + { "SubstructureRedirectMask",SubstructureRedirectMask }, + { "FocusChangeMask", FocusChangeMask }, + { "PropertyChangeMask", PropertyChangeMask }, + { "ColormapChangeMask", ColormapChangeMask }, + { "OwnerGrabButtonMask", OwnerGrabButtonMask }, + { 0L, 0 }}; + + +static QListViewItem* XServer_fill_screen_info( QListViewItem *lBox, QListViewItem *last, + Display *dpy, int scr, int default_scr) +{ + unsigned width, height; + double xres, yres; + int i, + ndepths, + *depths; + Screen *s = ScreenOfDisplay(dpy,scr); /* opaque structure */ + QListViewItem *item; + + /* + * there are 2.54 centimeters to an inch; so there are 25.4 millimeters. + * + * dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) + * = N pixels / (M inch / 25.4) + * = N * 25.4 pixels / M inch + */ + + xres = ((double)(DisplayWidth(dpy,scr) *25.4)/DisplayWidthMM(dpy,scr) ); + yres = ((double)(DisplayHeight(dpy,scr)*25.4)/DisplayHeightMM(dpy,scr)); + + item = new QListViewItem(lBox,last, i18n("Screen # %1").arg((int)scr,-1), + (scr==default_scr) ? i18n("(Default Screen)") : QString::null ); + item->setExpandable(true); + if (scr==default_scr) + item->setOpen(true); + last = new QListViewItem(item, i18n("Dimensions"), + i18n("%1 x %2 Pixel (%3 x %4 mm)") + .arg( (int)DisplayWidth(dpy,scr) ) + .arg( (int)DisplayHeight(dpy,scr) ) + .arg( (int)DisplayWidthMM(dpy,scr) ) + .arg( (int)DisplayHeightMM (dpy,scr) )); + + last = new QListViewItem(item, last, i18n("Resolution"), + i18n("%1 x %2 dpi") + .arg( (int)(xres+0.5) ) + .arg( (int)(yres+0.5) )); + + ndepths = 0; + depths = 0; + depths = XListDepths (dpy, scr, &ndepths); + if (depths) { + QString txt; + + for (i = 0; i < ndepths; i++) { + txt = txt + Value(depths[i]); + if (i < ndepths - 1) + txt = txt + QString::fromLatin1(", "); + } + + last = new QListViewItem(item, last, i18n("Depths (%1)").arg(ndepths,-1), txt); + XFree((char *) depths); + } + + last = new QListViewItem(item, last, i18n("Root Window ID"), + HexStr((unsigned long)RootWindow(dpy,scr),HEXDIGITS)); + last = new QListViewItem(item, last, i18n("Depth of Root Window"), + (DisplayPlanes (dpy, scr) == 1) + ? i18n("%1 plane").arg(DisplayPlanes(dpy,scr)) /*singular*/ + : i18n("%1 planes").arg(DisplayPlanes(dpy,scr)));/*plural*/ + last = new QListViewItem(item, last, i18n("Number of Colormaps"), + i18n("minimum %1, maximum %2") + .arg((int)MinCmapsOfScreen(s)).arg((int)MaxCmapsOfScreen(s))); + last = new QListViewItem(item, last, i18n("Default Colormap"), + Value((int)DefaultColormap(dpy,scr))); + last = new QListViewItem(item, last, i18n("Default Number of Colormap Cells"), + Value((int)DisplayCells(dpy, scr))); + last = new QListViewItem(item, last, i18n("Preallocated Pixels"), + i18n("Black %1, White %2") + .arg(KGlobal::locale()->formatNumber(BlackPixel(dpy,scr), 0)) + .arg(KGlobal::locale()->formatNumber(WhitePixel(dpy,scr), 0))); + + QString YES(i18n("Yes")); + QString NO(i18n("No")); + last = new QListViewItem(item, last, i18n("Options"), + i18n("backing-store: %1, save-unders: %2") + .arg( (DoesBackingStore(s) == NotUseful) ? NO : + ((DoesBackingStore(s) == Always) ? YES : i18n("When mapped")) ) + .arg( DoesSaveUnders(s) ? YES : NO )); + + XQueryBestSize (dpy, CursorShape, RootWindow(dpy,scr), 65535, 65535, + &width, &height); + last = new QListViewItem(item, last, i18n("Largest Cursor"), + (width == 65535 && height == 65535) + ? i18n("unlimited") : QString::fromLatin1("%1 x %2").arg(width).arg(height)); + + last = new QListViewItem(item, last, i18n("Current Input Event Mask"), + HexStr((unsigned long)EventMaskOfScreen(s),HEXDIGITS)); + item = last; + struct _event_table *etp; + for (etp=event_table; etp->name; etp++) { + if (EventMaskOfScreen(s) & etp->value) + item = new QListViewItem(last, item, + i18n("Event = %1").arg(HexStr(etp->value,HEXDIGITS)), + etp->name ); + } + + return item; +} + +static const QString Order( int order ) +{ + if (order==LSBFirst) return i18n("LSBFirst"); else + if (order==MSBFirst) return i18n("MSBFirst"); else + return i18n("Unknown Order %1").arg(order); +} + +static const QString BitString( unsigned long n ) +{ + return i18n("1 Bit", "%n Bits", n); // singular & plural form of "%d Bit" +} + +static const QString ByteString( unsigned long n ) +{ + /* explanation in BR #52640 (http://bugs.kde.org/show_bug.cgi?id=52640) */ + if (n == 1) + return i18n("1 Byte"); // singular form: "1 Byte" (yes, it's "1", not "%1"!) + + return i18n("%1 Bytes") // plural form: "%1 Bytes" + .arg(KGlobal::locale()->formatNumber(n,0)); +} + +static bool GetInfo_XServer_Generic( QListView *lBox ) +{ + /* Many parts of this source are taken from the X11-program "xdpyinfo" */ + + int i,n; + long req_size; + + Display *dpy; + XPixmapFormatValues *pmf; + + QString str,txt; + QListViewItem *last, *item, *next; + + dpy = XOpenDisplay(0); + if (!dpy) + return false; + + lBox->addColumn(i18n("Information") ); + lBox->addColumn(i18n("Value") ); + sorting_allowed = false; + + next = new QListViewItem(lBox, i18n("Server Information")); + next->setPixmap(0, SmallIcon("kcmx")); + next->setOpen(true); + next->setSelectable(false); + next->setExpandable(false); + + last = new QListViewItem(next, i18n("Name of the Display"), + DisplayString(dpy)); + + last = new QListViewItem(next, last, i18n("Vendor String"), QString::fromLatin1(ServerVendor(dpy))); + last = new QListViewItem(next, last, i18n("Vendor Release Number"), + Value((int)VendorRelease(dpy))); + + last = new QListViewItem(next, last, i18n("Version Number"), + QString::fromLatin1("%1.%2").arg((int)ProtocolVersion(dpy)) + .arg((int)ProtocolRevision(dpy))); + + last = item = new QListViewItem(next, last, i18n("Available Screens")); + last->setOpen(true); + last->setExpandable(true); + for (i=0; i<ScreenCount(dpy); i++) { + item = XServer_fill_screen_info(last, item, dpy, i, (int)DefaultScreen(dpy)); + if (i==0) item->setOpen(true); + } + + last = new QListViewItem( next, last, i18n("Supported Extensions") ); + item = last; + + int extCount; + char **extensions = XListExtensions( dpy, &extCount ); + for ( i = 0; i < extCount; i++ ) { + item = new QListViewItem( last, item, QString::fromLatin1( extensions[i] ) ); + } + XFreeExtensionList( extensions ); + + pmf = XListPixmapFormats(dpy, &n); + last = item = new QListViewItem(next, last, i18n("Supported Pixmap Formats")); + if (pmf) { + last->setExpandable(true); + for (i=0; i<n; i++) { + item = new QListViewItem(last, item, + i18n("Pixmap Format #%1").arg(i+1), + i18n("%1 BPP, Depth: %2, Scanline padding: %3") + .arg(pmf[i].bits_per_pixel) + .arg(BitString(pmf[i].depth)) + .arg(BitString(pmf[i].scanline_pad))); + } + XFree ((char *)pmf); + } + + req_size = XExtendedMaxRequestSize(dpy); + if (!req_size) req_size = XMaxRequestSize(dpy); + last = new QListViewItem(next, last, i18n("Maximum Request Size"), + ByteString(req_size*4)); + last = new QListViewItem(next, last, i18n("Motion Buffer Size"), + ByteString(XDisplayMotionBufferSize(dpy))); + + last = item = new QListViewItem(next, last, i18n("Bitmap")); + last->setExpandable(true); + item = new QListViewItem(last, item, i18n("Unit"), + Value(BitmapUnit(dpy)) ); + item = new QListViewItem(last, item, i18n("Order"), + Order(BitmapBitOrder(dpy))); + item = new QListViewItem(last, item, i18n("Padding"), + Value(BitmapPad(dpy))); + + last = new QListViewItem(next, last, i18n("Image Byte Order"), + Order(ImageByteOrder(dpy))); + + XCloseDisplay (dpy); + return true; +} + + + +/* +*************************************************************************** +*************************************************************************** +*************************************************************************** +*/ + + + +void KInfoListWidget::load() +{ + bool ok = false; + + lBox->clear(); + + /* Delete the user-visible ErrorString, before calling the + retrieve-function. If the function wants the widget to show + another string, then it change *GetInfo_ErrorString ! */ + ErrorString = i18n("No information available about %1.").arg(title) + + QString::fromLatin1("\n\n") + DEFAULT_ERRORSTRING; + GetInfo_ErrorString = &ErrorString; /* save the address of ErrorString */ + + sorting_allowed = true; /* the functions may set that */ + lBox->setSorting(-1); /* No Sorting per default */ + + if (getlistbox) + ok = (*getlistbox)(lBox); /* retrieve the information */ + + if (lBox->header()->count()<=1) + lBox->addColumn(title); /* set default title */ + + /* is the user allowed to use sorting ? */ + lBox->header()->setClickEnabled(sorting_allowed); + lBox->header()->setFont(KGlobalSettings::generalFont()); + lBox->setShowSortIndicator(sorting_allowed); + + if (ok) + { + widgetStack->raiseWidget(lBox); + } + else + { + NoInfoText->setText(ErrorString); + widgetStack->raiseWidget(NoInfoText); + } + + emit changed(false); +} + + +QString KInfoListWidget::quickHelp() const +{ + return i18n("<h1>System Information</h1>" + " All the information modules return information about a certain" + " aspect of your computer hardware or your operating system." + " Not all modules are available on all hardware architectures" + " and/or operating systems." ); +} + + +KInfoListWidget::KInfoListWidget(const QString &_title, QWidget *parent, const char *name, + bool _getlistbox(QListView *lbox)) + : KCModule(parent, name), + title(_title) +{ + KAboutData *about = + new KAboutData(I18N_NOOP("kcminfo"), + I18N_NOOP("KDE Panel System Information Control Module"), + 0, 0, KAboutData::License_GPL, + I18N_NOOP("(c) 1998 - 2002 Helge Deller")); + + about->addAuthor("Helge Deller", 0, "deller@kde.org"); + setAboutData( about ); + + setButtons(KCModule::Help); + getlistbox = _getlistbox; + GetInfo_ErrorString = 0; + QHBoxLayout *layout = new QHBoxLayout(this, 0, KDialog::spacingHint()); + widgetStack = new QWidgetStack(this); + layout->addWidget(widgetStack); + lBox = new QListView(widgetStack); + widgetStack->addWidget(lBox, 0); + lBox->setMinimumSize(200,120); + lBox->setFont(KGlobalSettings::generalFont()); /* default font */ + lBox->setAllColumnsShowFocus(true); + QWhatsThis::add( lBox, i18n( "This list displays system information on the selected category." ) ); + NoInfoText = new QLabel(widgetStack); + widgetStack->addWidget(NoInfoText, 1); + NoInfoText->setAlignment(AlignCenter | WordBreak); + widgetStack->raiseWidget(NoInfoText); + load(); +} + + + +/* Helper-function to read output from an external program */ +static int GetInfo_ReadfromPipe( QListView *lBox, const char *FileName, bool WithEmptyLines = true ) +{ + FILE *pipe; + QListViewItem* olditem = 0L; + QString s; + + if ((pipe = popen(FileName, "r")) == NULL) { + pclose(pipe); + return 0; + } + + QTextStream t(pipe, IO_ReadOnly); + + while (!t.atEnd()) { + s = t.readLine(); + if (!WithEmptyLines && s.length()==0) + continue; + olditem = new QListViewItem(lBox, olditem, s); + } + + pclose(pipe); + + return (lBox->childCount()); +} + +/* +*************************************************************************** +** Include system-specific code ** +*************************************************************************** +*/ + +#ifdef __linux__ +#include "info_linux.cpp" +#elif defined(sgi) && sgi +#include "info_sgi.cpp" +#elif defined(__FreeBSD__) || defined (__DragonFly__) +#include "info_fbsd.cpp" +#elif __hpux +#include "info_hpux.cpp" +#elif __NetBSD__ +#include "info_netbsd.cpp" +#elif __OpenBSD__ +#include "info_openbsd.cpp" +#elif defined(__svr4__) && defined(sun) +#include "info_solaris.cpp" +#elif __svr4__ +#include "info_svr4.cpp" +#elif _AIX +#include "info_aix.cpp" +#elif defined(__APPLE__) +#include "info_osx.cpp" +#else +#include "info_generic.cpp" /* Default for unsupportet systems.... */ +#endif + +/* +*************************************************************************** +** End of: Include system-specific code ** +*************************************************************************** +*/ |