You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
496 lines
16 KiB
496 lines
16 KiB
/*
|
|
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 <tqheader.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqlayout.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 TQString *GetInfo_ErrorString; /* should always point to:
|
|
KInfoListWidget::ErrorString */
|
|
static bool sorting_allowed; /* is sorting allowed by user ? */
|
|
|
|
|
|
|
|
#if defined(__linux__)
|
|
# define DEFAULT_ERRORSTRING TQString::null /* i18n("Maybe the proc-filesystem is not enabled in Linux-Kernel.") */
|
|
#elif defined(__hpux)
|
|
# define DEFAULT_ERRORSTRING TQString::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 TQString Value( int val, int numbers=1 )
|
|
{
|
|
return KGlobal::locale()->formatNumber(val, 0).rightJustify(numbers);
|
|
}
|
|
|
|
static const TQString HexStr(unsigned long val, int digits )
|
|
{
|
|
TQString hexstr;
|
|
int i;
|
|
hexstr = TQString::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 TQListViewItem* XServer_fill_screen_info( TQListViewItem *lBox, TQListViewItem *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 */
|
|
TQListViewItem *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 TQListViewItem(lBox,last, i18n("Screen # %1").arg((int)scr,-1),
|
|
(scr==default_scr) ? i18n("(Default Screen)") : TQString::null );
|
|
item->setExpandable(true);
|
|
if (scr==default_scr)
|
|
item->setOpen(true);
|
|
last = new TQListViewItem(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 TQListViewItem(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) {
|
|
TQString txt;
|
|
|
|
for (i = 0; i < ndepths; i++) {
|
|
txt = txt + Value(depths[i]);
|
|
if (i < ndepths - 1)
|
|
txt = txt + TQString::fromLatin1(", ");
|
|
}
|
|
|
|
last = new TQListViewItem(item, last, i18n("Depths (%1)").arg(ndepths,-1), txt);
|
|
XFree((char *) depths);
|
|
}
|
|
|
|
last = new TQListViewItem(item, last, i18n("Root Window ID"),
|
|
HexStr((unsigned long)RootWindow(dpy,scr),HEXDIGITS));
|
|
last = new TQListViewItem(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 TQListViewItem(item, last, i18n("Number of Colormaps"),
|
|
i18n("minimum %1, maximum %2")
|
|
.arg((int)MinCmapsOfScreen(s)).arg((int)MaxCmapsOfScreen(s)));
|
|
last = new TQListViewItem(item, last, i18n("Default Colormap"),
|
|
Value((int)DefaultColormap(dpy,scr)));
|
|
last = new TQListViewItem(item, last, i18n("Default Number of Colormap Cells"),
|
|
Value((int)DisplayCells(dpy, scr)));
|
|
last = new TQListViewItem(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)));
|
|
|
|
TQString YES(i18n("Yes"));
|
|
TQString NO(i18n("No"));
|
|
last = new TQListViewItem(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 TQListViewItem(item, last, i18n("Largest Cursor"),
|
|
(width == 65535 && height == 65535)
|
|
? i18n("unlimited") : TQString::fromLatin1("%1 x %2").arg(width).arg(height));
|
|
|
|
last = new TQListViewItem(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 TQListViewItem(last, item,
|
|
i18n("Event = %1").arg(HexStr(etp->value,HEXDIGITS)),
|
|
etp->name );
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
static const TQString 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 TQString BitString( unsigned long n )
|
|
{
|
|
return i18n("1 Bit", "%n Bits", n); // singular & plural form of "%d Bit"
|
|
}
|
|
|
|
static const TQString 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( TQListView *lBox )
|
|
{
|
|
/* Many parts of this source are taken from the X11-program "xdpyinfo" */
|
|
|
|
int i,n;
|
|
long req_size;
|
|
|
|
Display *dpy;
|
|
XPixmapFormatValues *pmf;
|
|
|
|
TQString str,txt;
|
|
TQListViewItem *last, *item, *next;
|
|
|
|
dpy = XOpenDisplay(0);
|
|
if (!dpy)
|
|
return false;
|
|
|
|
lBox->addColumn(i18n("Information") );
|
|
lBox->addColumn(i18n("Value") );
|
|
sorting_allowed = false;
|
|
|
|
next = new TQListViewItem(lBox, i18n("Server Information"));
|
|
next->setPixmap(0, SmallIcon("kcmx"));
|
|
next->setOpen(true);
|
|
next->setSelectable(false);
|
|
next->setExpandable(false);
|
|
|
|
last = new TQListViewItem(next, i18n("Name of the Display"),
|
|
DisplayString(dpy));
|
|
|
|
last = new TQListViewItem(next, last, i18n("Vendor String"), TQString::fromLatin1(ServerVendor(dpy)));
|
|
last = new TQListViewItem(next, last, i18n("Vendor Release Number"),
|
|
Value((int)VendorRelease(dpy)));
|
|
|
|
last = new TQListViewItem(next, last, i18n("Version Number"),
|
|
TQString::fromLatin1("%1.%2").arg((int)ProtocolVersion(dpy))
|
|
.arg((int)ProtocolRevision(dpy)));
|
|
|
|
last = item = new TQListViewItem(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 TQListViewItem( next, last, i18n("Supported Extensions") );
|
|
item = last;
|
|
|
|
int extCount;
|
|
char **extensions = XListExtensions( dpy, &extCount );
|
|
for ( i = 0; i < extCount; i++ ) {
|
|
item = new TQListViewItem( last, item, TQString::fromLatin1( extensions[i] ) );
|
|
}
|
|
XFreeExtensionList( extensions );
|
|
|
|
pmf = XListPixmapFormats(dpy, &n);
|
|
last = item = new TQListViewItem(next, last, i18n("Supported Pixmap Formats"));
|
|
if (pmf) {
|
|
last->setExpandable(true);
|
|
for (i=0; i<n; i++) {
|
|
item = new TQListViewItem(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 TQListViewItem(next, last, i18n("Maximum Request Size"),
|
|
ByteString(req_size*4));
|
|
last = new TQListViewItem(next, last, i18n("Motion Buffer Size"),
|
|
ByteString(XDisplayMotionBufferSize(dpy)));
|
|
|
|
last = item = new TQListViewItem(next, last, i18n("Bitmap"));
|
|
last->setExpandable(true);
|
|
item = new TQListViewItem(last, item, i18n("Unit"),
|
|
Value(BitmapUnit(dpy)) );
|
|
item = new TQListViewItem(last, item, i18n("Order"),
|
|
Order(BitmapBitOrder(dpy)));
|
|
item = new TQListViewItem(last, item, i18n("Padding"),
|
|
Value(BitmapPad(dpy)));
|
|
|
|
last = new TQListViewItem(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)
|
|
+ TQString::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);
|
|
}
|
|
|
|
|
|
TQString 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 TQString &_title, TQWidget *parent, const char *name,
|
|
bool _getlistbox(TQListView *lbox))
|
|
: KCModule(parent, name),
|
|
title(_title)
|
|
{
|
|
KAboutData *about =
|
|
new KAboutData(I18N_NOOP("kcminfo"),
|
|
I18N_NOOP("TDE 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;
|
|
TQHBoxLayout *layout = new TQHBoxLayout(this, 0, KDialog::spacingHint());
|
|
widgetStack = new TQWidgetStack(this);
|
|
layout->addWidget(widgetStack);
|
|
lBox = new TQListView(widgetStack);
|
|
widgetStack->addWidget(lBox, 0);
|
|
lBox->setMinimumSize(200,120);
|
|
lBox->setFont(KGlobalSettings::generalFont()); /* default font */
|
|
lBox->setAllColumnsShowFocus(true);
|
|
TQWhatsThis::add( lBox, i18n( "This list displays system information on the selected category." ) );
|
|
NoInfoText = new TQLabel(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( TQListView *lBox, const char *FileName, bool WithEmptyLines = true )
|
|
{
|
|
FILE *pipe;
|
|
TQListViewItem* olditem = 0L;
|
|
TQString s;
|
|
|
|
if ((pipe = popen(FileName, "r")) == NULL) {
|
|
pclose(pipe);
|
|
return 0;
|
|
}
|
|
|
|
TQTextStream t(pipe, IO_ReadOnly);
|
|
|
|
while (!t.atEnd()) {
|
|
s = t.readLine();
|
|
if (!WithEmptyLines && s.length()==0)
|
|
continue;
|
|
olditem = new TQListViewItem(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 **
|
|
***************************************************************************
|
|
*/
|