Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEduardo Silva <edsiper@monotop.(none)>2007-09-20 15:52:28 (GMT)
committer Eduardo Silva <edsiper@monotop.(none)>2007-09-20 15:52:28 (GMT)
commit99ce1835e4d8cb176ebdf12572a8e193b1dd1e88 (patch)
treee3dd8a322a633862e3879d2a11aa4ef1443fac84
parent0f2a58d737b29fb765c09a2c49135d50f01e25d4 (diff)
DevConsole: New PyXRes class and XServer interface (similar to xrestop)
-rwxr-xr-xservices/console/console.py1
-rw-r--r--services/console/interface/xserver/Makefile.am4
-rw-r--r--services/console/interface/xserver/__init__.py1
-rw-r--r--services/console/interface/xserver/xserver.py111
-rw-r--r--services/console/lib/Makefile.am4
-rw-r--r--services/console/lib/pyxres.py256
6 files changed, 376 insertions, 1 deletions
diff --git a/services/console/console.py b/services/console/console.py
index 4fb3609..9aebd2d 100755
--- a/services/console/console.py
+++ b/services/console/console.py
@@ -51,6 +51,7 @@ class Console:
self._load_interface('xo', 'XO Resources')
self._load_interface('network', 'Network')
+ self._load_interface('xserver', 'X Server')
self._load_interface('memphis', 'Memphis')
self._load_interface('logviewer', 'Log Viewer')
self._load_interface('terminal', 'Terminal')
diff --git a/services/console/interface/xserver/Makefile.am b/services/console/interface/xserver/Makefile.am
new file mode 100644
index 0000000..c77cca2
--- /dev/null
+++ b/services/console/interface/xserver/Makefile.am
@@ -0,0 +1,4 @@
+sugardir = $(pkgdatadir)/services/console/interface/xserver
+sugar_PYTHON = \
+ __init__.py \
+ xserver.py
diff --git a/services/console/interface/xserver/__init__.py b/services/console/interface/xserver/__init__.py
new file mode 100644
index 0000000..88b634f
--- /dev/null
+++ b/services/console/interface/xserver/__init__.py
@@ -0,0 +1 @@
+from xserver import Interface
diff --git a/services/console/interface/xserver/xserver.py b/services/console/interface/xserver/xserver.py
new file mode 100644
index 0000000..2ab1860
--- /dev/null
+++ b/services/console/interface/xserver/xserver.py
@@ -0,0 +1,111 @@
+# Copyright (C) 2007, Eduardo Silva <edsiper@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+import gobject
+from pyxres import XRes
+from ui.treeview import TreeView
+
+class XorgView(TreeView):
+ def __init__(self):
+ col_names = []
+ col_names.append({'index': 0, 'name': 'PID'})
+ col_names.append({'index': 1, 'name': 'Resource Base'})
+ col_names.append({'index': 2, 'name': 'Pixmap Bytes'})
+ col_names.append({'index': 3, 'name': 'Other'})
+ col_names.append({'index': 4, 'name': 'Total'})
+ col_names.append({'index': 5, 'name': 'Window Name'})
+
+ self._window_iter = []
+
+ cols_type = [str, str, str, str, str, str]
+ TreeView.__init__(self, cols_type, col_names)
+
+ self._xres = XRes()
+ self._display = self._xres.open_display()
+ self.show_all()
+ gobject.timeout_add(1500, self._update_data)
+
+ def _nice_bytes(self, bytes):
+ prefix = "B"
+ value = bytes
+
+ if bytes/1024:
+ prefix = "K"
+ value = (bytes/1024)
+
+ return "%s%s" % (value, prefix)
+
+ def _update_data(self):
+ windows = self._xres.get_windows(self._display)
+ print windows
+ for w in windows:
+ row = []
+ row.append({'index':0, 'info': w.pid})
+
+ bytes = self._nice_bytes(w.pixmap_bytes)
+ obytes = self._nice_bytes(w.other_bytes)
+ tbytes = self._nice_bytes(w.pixmap_bytes+w.other_bytes)
+
+ row.append({'index':1, 'info': hex(w.resource_base)})
+ row.append({'index':2, 'info': bytes})
+ row.append({'index':3, 'info': obytes})
+ row.append({'index':4, 'info': tbytes})
+ row.append({'index':5, 'info': w.wm_name})
+
+ iter = self._get_window_iter(w.pid)
+ if not iter:
+ iter = self.add_row(row)
+ self._set_window_iter(iter, w.pid)
+ else:
+ self.update_row(iter, row)
+
+ self._clear_down_windows(windows)
+ return True
+
+ def _set_window_iter(self, iter, pid):
+ self._window_iter.append([iter, pid])
+
+ def _remove_iface_iter(self, search_iter):
+ i = 0
+ for [iter, pid] in self._window_iter:
+ if iter == search_iter:
+ del self._window_iter[i]
+ return
+ i+=1
+
+ def _get_window_iter(self, wpid):
+ for [iter, pid] in self._window_iter:
+ if wpid == pid:
+ return iter
+
+ return None
+
+ def _clear_down_windows(self, windows):
+ for [iter, pid] in self._window_iter:
+ found = False
+ for w in windows:
+ if w.pid == pid:
+ found = True
+ break
+
+ if not found:
+ self.remove_row(iter)
+ self._remove_window_iter(iter)
+
+class Interface(object):
+ def __init__(self):
+ self.widget = XorgView()
diff --git a/services/console/lib/Makefile.am b/services/console/lib/Makefile.am
index 0d4dcce..238c435 100644
--- a/services/console/lib/Makefile.am
+++ b/services/console/lib/Makefile.am
@@ -1,4 +1,6 @@
SUBDIRS = procmem graphics net ui
sugardir = $(pkgdatadir)/shell/console/lib
-sugar_PYTHON =
+sugar_PYTHON = \
+ pyxres.py
+
diff --git a/services/console/lib/pyxres.py b/services/console/lib/pyxres.py
new file mode 100644
index 0000000..91c3542
--- /dev/null
+++ b/services/console/lib/pyxres.py
@@ -0,0 +1,256 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2007, Eduardo Silva <edsiper@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from ctypes import *
+
+# XText Property
+class _XTextProperty(Structure):
+ pass
+
+_XTextProperty._fields_ = [("value", c_char_p),\
+ ("encoding", c_ulong),\
+ ("format", c_int),\
+ ("nitems", c_ulong)]
+
+# XResType Structure
+class _XResTypeStruct(Structure):
+ pass
+
+_XResTypeStruct._fields_ = [("resource_type", c_ulong),\
+ ("count", c_uint)]
+
+_ATOMNAMES = ["PIXMAP",\
+ "WINDOW",\
+ "GC",\
+ "FONT",\
+ "GLYPHSET",\
+ "PICTURE",\
+ "COLORMAP ENTRY",\
+ "PASSIVE GRAB",\
+ "CURSOR",\
+ "_NET_CLIENT_LIST",\
+ "_NET_WM_PID",\
+ "_NET_WM_NAME",\
+ "UTF8_STRING",\
+ "WM_NAME", # FIXME!
+ "CARDINAL" # FIXME!
+ ]
+
+_ATOM_PIXMAP = 0
+_ATOM_WINDOW = 1
+_ATOM_GC = 2
+_ATOM_FONT = 3
+_ATOM_GLYPHSET = 4
+_ATOM_PICTURE = 5
+_ATOM_COLORMAP_ENTRY = 6
+_ATOM_PASSIVE_GRAB = 7
+_ATOM_CURSOR = 8
+_ATOM_NET_CLIENT_LIST = 9
+_ATOM_NET_WM_PID = 10
+_ATOM_NET_WM_NAME = 11
+_ATOM_UTF8_STRING = 12
+_ATOM_WM_NAME = 13
+_ATOM_CARDINAL = 14
+
+# XText Property
+class _XTextProperty(Structure):
+ pass
+
+_XTextProperty._fields_ = [("value", c_char_p),\
+ ("encoding", c_ulong),\
+ ("format", c_int),\
+ ("nitems", c_ulong)]
+
+class XRes(object):
+ _XRESLIB = "libXRes.so"
+ _XMULIB = "libXmu.so.6"
+
+ def __init__(self):
+ self._lib = CDLL(self._XRESLIB)
+ self._lib_xmu = CDLL(self._XMULIB)
+
+ def _set_atoms(self, display):
+ self.atoms = []
+ for atom in _ATOMNAMES:
+ atom_value = self._lib.XInternAtom(display, atom, True)
+ self.atoms.append(atom_value)
+
+ def open_display(self, display=None):
+ display = self._lib.XOpenDisplay(display)
+ self._set_atoms(display)
+ return display
+
+ # Return an array with XRestTypes:
+ #
+ # XResType.resource_type (Atom_type)
+ # XResTyoe.count
+ def get_resources(self, display, resource_base):
+ n_types = c_long()
+ types = pointer(_XResTypeStruct())
+ self._lib.XResQueryClientResources(display, resource_base, \
+ byref(n_types), byref(types))
+
+ pytypes = []
+ for t in types[:n_types.value]:
+ pytypes.append(t)
+
+ return pytypes
+
+ def get_windows(self, display):
+ self._windows = []
+ root = self._lib.XDefaultRootWindow(display)
+ self._lookat(display, root)
+ return self._windows
+
+ def _lookat(self, display, win_root):
+ wp = self._get_window_properties (display, win_root)
+
+ if wp:
+ self._windows.append(wp)
+
+ w = None
+ dummy = self._Window()
+ children = self._Window()
+ nchildren = c_uint()
+
+ r = self._lib.XQueryTree(display, win_root, byref(dummy), \
+ byref(dummy), byref(children), byref(nchildren))
+
+ for client in children[:nchildren.value]:
+ cli = self._lib_xmu.XmuClientWindow (display, client)
+ if client is not None:
+ wp = self._get_window_properties (display, cli)
+ if wp:
+ self._windows.append(wp)
+
+ def _get_window_properties(self, display, w):
+ cliargv = c_char_p()
+ cliargc = c_long()
+ machtp = pointer(_XTextProperty())
+ nametp = _XTextProperty()
+ w_name = None
+
+ if not self._lib.XGetWMClientMachine (display, w, byref(machtp)):
+ machtp.value = None
+ machtp.encoding = None
+
+ if not self._lib.XGetCommand(display, w, byref(cliargv), byref(cliargc)):
+ return
+
+ if self._lib.XGetWMName(display, w, byref(nametp)):
+ w_name = nametp.value
+
+ bytes = c_ulong()
+ self._lib.XResQueryClientPixmapBytes(display, w, byref(bytes))
+ w_pixmaps = bytes.value
+
+ type = self._Atom()
+ format = c_int()
+ n_items = c_ulong()
+ bytes_after = c_int()
+ w_pid = pointer(c_long())
+ wname = c_char_p()
+
+ self._lib.XGetWindowProperty(display, w,\
+ self.atoms[_ATOM_NET_WM_PID],
+ 0, 2L,\
+ False, self.atoms[_ATOM_CARDINAL],\
+ byref(type), byref(format), \
+ byref(n_items), byref(bytes_after), \
+ byref(w_pid))
+
+
+ # Calc aditional X resources by window
+ res = self.get_resources(display, w)
+
+ n_windows = 0
+ n_gcs = 0
+ n_pictures = 0
+ n_glyphsets = 0
+ n_fonts = 0
+ n_colormaps = 0
+ n_passive_grabs = 0
+ n_cursors = 0
+ n_other = 0
+
+ for r in res:
+ if r.resource_type == self.atoms[_ATOM_WINDOW]:
+ n_windows += r.count
+ elif r.resource_type == self.atoms[_ATOM_GC]:
+ n_gcs += r.count
+ elif r.resource_type == self.atoms[_ATOM_PICTURE]:
+ n_pictures += r.count
+ elif r.resource_type == self.atoms[_ATOM_GLYPHSET]:
+ n_glyphsets += r.count
+ elif r.resource_type == self.atoms[_ATOM_FONT]:
+ n_fonts += r.count
+ elif r.resource_type == self.atoms[_ATOM_COLORMAP_ENTRY]:
+ n_colormaps += r.count
+ elif r.resource_type == self.atoms[_ATOM_PASSIVE_GRAB]:
+ n_passive_grabs += r.count
+ elif r.resource_type == self.atoms[_ATOM_CURSOR]:
+ n_cursors += r.count
+ else:
+ n_other += r.count
+
+ other_bytes = n_windows * 24
+ other_bytes += n_gcs * 24
+ other_bytes += n_pictures * 24
+ other_bytes += n_glyphsets * 24
+ other_bytes += n_fonts * 1024
+ other_bytes += n_colormaps * 24
+ other_bytes += n_passive_grabs * 24
+ other_bytes += n_cursors * 24
+ other_bytes += n_other * 24
+
+ window = Window(w, w_pid.contents.value, w_pixmaps, \
+ n_windows, n_gcs, n_fonts, n_glyphsets, n_pictures,\
+ n_colormaps, n_passive_grabs, n_cursors, n_other,\
+ other_bytes, w_name)
+
+ return window
+
+ # Data types
+ def _Window(self):
+ return pointer(c_ulong())
+
+ def _Atom(self, data=0):
+ return pointer(c_ulong(data))
+
+class Window(object):
+ def __init__(self, resource_base, pid, pixmap_bytes=0,\
+ n_windows=0, n_gcs=0, n_fonts=0, n_glyphsets=0, n_pictures=0,\
+ n_colormaps=0, n_passive_grabs=0, n_cursors=0, n_other=0,\
+ other_bytes=0, wm_name=None):
+
+ self.resource_base = resource_base
+ self.pid = pid
+ self.pixmap_bytes = pixmap_bytes
+
+ self.n_windows = n_windows
+ self.n_gcs = n_gcs
+ self.n_fonts = n_fonts
+ self.n_glyphsets = n_glyphsets
+ self.n_pictures = n_pictures
+ self.n_colormaps = n_colormaps
+ self.n_passive_grabs = n_passive_grabs
+ self.n_cursors = n_cursors
+ self.n_other = n_other
+
+ self.other_bytes = other_bytes
+ self.wm_name = wm_name