DevConsole: New PyXRes class and XServer interface (similar to xrestop)
This commit is contained in:
parent
0f2a58d737
commit
99ce1835e4
@ -51,6 +51,7 @@ class Console:
|
|||||||
|
|
||||||
self._load_interface('xo', 'XO Resources')
|
self._load_interface('xo', 'XO Resources')
|
||||||
self._load_interface('network', 'Network')
|
self._load_interface('network', 'Network')
|
||||||
|
self._load_interface('xserver', 'X Server')
|
||||||
self._load_interface('memphis', 'Memphis')
|
self._load_interface('memphis', 'Memphis')
|
||||||
self._load_interface('logviewer', 'Log Viewer')
|
self._load_interface('logviewer', 'Log Viewer')
|
||||||
self._load_interface('terminal', 'Terminal')
|
self._load_interface('terminal', 'Terminal')
|
||||||
|
4
services/console/interface/xserver/Makefile.am
Normal file
4
services/console/interface/xserver/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
sugardir = $(pkgdatadir)/services/console/interface/xserver
|
||||||
|
sugar_PYTHON = \
|
||||||
|
__init__.py \
|
||||||
|
xserver.py
|
1
services/console/interface/xserver/__init__.py
Normal file
1
services/console/interface/xserver/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from xserver import Interface
|
111
services/console/interface/xserver/xserver.py
Normal file
111
services/console/interface/xserver/xserver.py
Normal file
@ -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()
|
@ -1,4 +1,6 @@
|
|||||||
SUBDIRS = procmem graphics net ui
|
SUBDIRS = procmem graphics net ui
|
||||||
|
|
||||||
sugardir = $(pkgdatadir)/shell/console/lib
|
sugardir = $(pkgdatadir)/shell/console/lib
|
||||||
sugar_PYTHON =
|
sugar_PYTHON = \
|
||||||
|
pyxres.py
|
||||||
|
|
||||||
|
256
services/console/lib/pyxres.py
Normal file
256
services/console/lib/pyxres.py
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user