[Ocfs2-tools-commits] manish commits r261 - in trunk: . ocfs2tool
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Mon Sep 27 01:00:01 CDT 2004
Author: manish
Date: 2004-09-27 00:59:59 -0500 (Mon, 27 Sep 2004)
New Revision: 261
Added:
trunk/acinclude.m4
trunk/ocfs2tool/
trunk/ocfs2tool/Makefile
trunk/ocfs2tool/bitmap.py
trunk/ocfs2tool/browser.py
trunk/ocfs2tool/cellmap.defs
trunk/ocfs2tool/cellmap.override
trunk/ocfs2tool/format.py
trunk/ocfs2tool/general.py
trunk/ocfs2tool/guiutil.py
trunk/ocfs2tool/main.py
trunk/ocfs2tool/nodemap.py
trunk/ocfs2tool/ocfs2module.c
trunk/ocfs2tool/ocfs2tool
trunk/ocfs2tool/ocfs2tool.8.in
trunk/ocfs2tool/ocfsbitmap.c
trunk/ocfs2tool/ocfsbitmap.h
trunk/ocfs2tool/ocfscellmap.c
trunk/ocfs2tool/ocfscellmap.h
trunk/ocfs2tool/ocfsmarshal.list
trunk/ocfs2tool/ocfsplist.c
trunk/ocfs2tool/ocfsplist.h
trunk/ocfs2tool/process.py
Modified:
trunk/Config.make.in
trunk/Makefile
trunk/autogen.sh
trunk/configure.in
Log:
Initial landing of ocfs2tool
Modified: trunk/Config.make.in
===================================================================
--- trunk/Config.make.in 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/Config.make.in 2004-09-27 05:59:59 UTC (rev 261)
@@ -21,6 +21,7 @@
datadir = @datadir@
sysconfdir = @sysconfdir@
mandir = @mandir@
+pyexecdir = @pyexecdir@
top_builddir = .
@@ -42,10 +43,20 @@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
+PYTHON = @PYTHON@
+PYTHON_INCLUDES = @PYTHON_INCLUDES@
+
+PYGTK_CFLAGS = @PYGTK_CFLAGS@
+PYGTK_LIBS = @PYGTK_LIBS@
+
+PYGTK_CODEGEN = @PYGTK_CODEGEN@
+PYGTK_DEFSDIR = @PYGTK_DEFSDIR@
+
BUILD_OCFSTOOL = @BUILD_OCFSTOOL@
BUILD_DEBUGOCFS2 = @BUILD_DEBUGOCFS2@
Modified: trunk/Makefile
===================================================================
--- trunk/Makefile 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/Makefile 2004-09-27 05:59:59 UTC (rev 261)
@@ -29,7 +29,7 @@
endif
ifdef BUILD_OCFSTOOL
-SUBDIRS += ocfstool
+SUBDIRS += ocfs2tool
endif
SUBDIRS += vendor
Added: trunk/acinclude.m4
===================================================================
--- trunk/acinclude.m4 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/acinclude.m4 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,29 @@
+## Add your own autoconf macros here.
+
+## Find the install dirs for the python installation.
+## By James Henstridge
+
+dnl a macro to check for ability to create python extensions
+dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
+dnl function also defines PYTHON_INCLUDES
+AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
+[AC_REQUIRE([AM_PATH_PYTHON])
+AC_MSG_CHECKING(for headers required to compile python extensions)
+dnl deduce PYTHON_INCLUDES
+py_prefix=`$PYTHON -c "import sys; print sys.prefix"`
+py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"`
+PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
+if test "$py_prefix" != "$py_exec_prefix"; then
+ PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
+fi
+AC_SUBST(PYTHON_INCLUDES)
+dnl check if the headers exist:
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
+AC_TRY_CPP([#include <Python.h>],dnl
+[AC_MSG_RESULT(found)
+$1],dnl
+[AC_MSG_RESULT(not found)
+$2])
+CPPFLAGS="$save_CPPFLAGS"
+])
Modified: trunk/autogen.sh
===================================================================
--- trunk/autogen.sh 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/autogen.sh 2004-09-27 05:59:59 UTC (rev 261)
@@ -1,5 +1,25 @@
#!/bin/sh
-aclocal
+PROJECT=ocfs2-tools
+
+if (automake-1.9 --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal-1.9
+elif (automake-1.8 --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal-1.8
+elif (automake-1.7 --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal-1.7
+elif (automake-1.6 --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal-1.6
+else
+ echo
+ echo " You must have automake 1.6 or newer installed to compile $PROJECT."
+ echo " Download the appropriate package for your distribution,"
+ echo " or get the source tarball at ftp://ftp.gnu.org/pub/gnu/automake/"
+ echo
+ exit 1
+fi
+
+rm -rf autom4te.cache
+$ACLOCAL
autoconf
./configure "$@"
Modified: trunk/configure.in
===================================================================
--- trunk/configure.in 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/configure.in 2004-09-27 05:59:59 UTC (rev 261)
@@ -124,7 +124,8 @@
AC_MSG_RESULT($enable_debugexe)
GLIB_REQUIRED_VERSION=2.0.6
-GTK_REQUIRED_VERSION=2.0.6
+GTK_REQUIRED_VERSION=2.2.4
+PYGTK_REQUIRED_VERSION=1.99.16
AM_PATH_GLIB_2_0($GLIB_REQUIRED_VERSION, :,
AC_MSG_ERROR([Glib $GLIB_REQUIRED_VERSION or better is required.]))
@@ -144,17 +145,33 @@
BUILD_OCFSTOOL=
dnl AC_ARG_ENABLE(ocfstool, [ --enable-ocfstool=[yes/no] Build GUI frontend [default=yes]],,enable_ocfstool=yes)
-dnl
-dnl if test "x$enable_ocfstool" = "xyes"; then
-dnl AM_PATH_GTK_2_0($GTK_REQUIRED_VERSION, have_gtk=yes, have_gtk=no)
-dnl
-dnl if test "x$have_gtk" = "xyes"; then
-dnl BUILD_OCFSTOOL=yes
-dnl else
-dnl AC_MSG_WARN([GTK+ $GTK_REQUIRED_VERSION or better not found, ocfstool will not be built])
-dnl fi
-dnl fi
+AC_ARG_ENABLE(ocfstool, [ --enable-ocfstool=[yes/no] Build GUI frontend [default=no]],,enable_ocfstool=no)
+if test "x$enable_ocfstool" = "xyes"; then
+ dnl check for Python
+ AM_PATH_PYTHON(2.2)
+ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)])
+
+ dnl check for GTK
+ PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRED_VERSION)
+
+ dnl check for PyGTK
+ PKG_CHECK_MODULES(PYGTK, pygtk-2.0 >= $PYGTK_REQUIRED_VERSION)
+ AC_SUBST(PYGTK_CFLAGS)
+
+ AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no)
+ if test "x$PYGTK_CODEGEN" = xno; then
+ AC_MSG_ERROR(could not find pygtk-codegen-2.0 script)
+ fi
+
+ AC_MSG_CHECKING(for pygtk defs)
+ PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
+ AC_SUBST(PYGTK_DEFSDIR)
+ AC_MSG_RESULT($PYGTK_DEFSDIR)
+
+ BUILD_OCFSTOOL=yes
+fi
+
AC_SUBST(BUILD_OCFSTOOL)
AC_OUTPUT([
@@ -162,6 +179,7 @@
libocfs2/ocfs2_err.et
debugfs.ocfs2/debugfs.ocfs2.8
mkfs.ocfs2/mkfs.ocfs2.8
+ocfs2tool/ocfs2tool.8
ocfs_uid_gen/ocfs_uid_gen.8
load_ocfs/load_ocfs.8
load_ocfs/ocfs.conf.5
Added: trunk/ocfs2tool/Makefile
===================================================================
--- trunk/ocfs2tool/Makefile 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/Makefile 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,70 @@
+TOPDIR = ..
+
+include $(TOPDIR)/Preamble.make
+
+WARNINGS = -Wall
+
+ifdef OCFS_DEBUG
+OPTS = -g
+endif
+OPTS = -g
+
+CFLAGS = $(OPTS) $(WARNINGS) -fPIC
+
+LIBOCFS2_CFLAGS = -I$(TOPDIR)/libocfs2/include
+LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
+
+DEFINES = -DOCFS2_FLAT_INCLUDES -DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED
+INCLUDES = $(LIBOCFS2_CFLAGS) $(PYTHON_INCLUDES) $(PYGTK_CFLAGS) $(GTK_CFLAGS)
+
+OPTIMIZE = -O2
+OPTIMIZE = -O0
+
+CFLAGS += $(OPTIMIZE)
+
+CBITS = \
+ ocfsbitmap.c \
+ ocfscellmap.c \
+ ocfsplist.c
+
+HBITS = $(subst .c,.h,$(CBITS))
+
+CFILES = $(CBITS) ocfs2module.c
+HFILES = $(HBITS)
+
+ALL = $(CFILES) ocfsmarshal.c cellmap.c
+
+OBJS = $(subst .c,.o,$(ALL))
+
+MANS = ocfs2tool.8
+
+LIBRARIES = ocfs2module.so
+
+DIST_FILES = $(CFILES) $(HFILES) ocfs2tool ocfsmarshal.list \
+ cellmap.defs cellmap.override ocfs2tool.8.in
+
+ocfsmarshal.h: ocfsmarshal.list
+ $(GLIB_GENMARSHAL) --prefix=_ocfs_marshal ocfsmarshal.list --header >> xgen-omh \
+ && (cmp -s xgen-omh $(@F) || cp xgen-omh $(@F)) \
+ && rm -f xgen-omh xgen-omh~
+
+ocfsmarshal.c: ocfsmarshal.list
+ echo "#include \"ocfsmarshal.h\"" >> xgen-omc \
+ && $(GLIB_GENMARSHAL) --prefix=_ocfs_marshal ocfsmarshal.list --body >> xgen-omc \
+ && cp xgen-omc $(@F) \
+ && rm -f xgen-omc xgen-omc~
+
+ocfscellmap.o: ocfscellmap.c ocfsmarshal.h
+ $(CC) $(CFLAGS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(INCLUDES) $(DEFINES) -o $@ -c $<
+
+cellmap.c: cellmap.defs cellmap.override
+ $(PYGTK_CODEGEN) --prefix cellmap \
+ --register $(PYGTK_DEFSDIR)/gdk-types.defs \
+ --register $(PYGTK_DEFSDIR)/gtk-types.defs \
+ --override cellmap.override \
+ cellmap.defs > $@
+
+ocfs2module.so: $(OBJS)
+ $(LINK) -shared $(LIBOCFS2_LIBS) $(COM_ERR_LIBS) $(GTK_LIBS)
+
+include $(TOPDIR)/Postamble.make
Added: trunk/ocfs2tool/bitmap.py
===================================================================
--- trunk/ocfs2tool/bitmap.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/bitmap.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,24 @@
+import gtk
+
+import ocfs2
+
+class Bitmap:
+ def __init__(self, device=None, advanced=False):
+ self.device = device
+
+ info = self.info()
+
+ if info:
+ self.widget = gtk.ScrolledWindow()
+ self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.widget.set_border_width(4)
+ self.widget.add(info)
+ else:
+ self.widget = gtk.Label('Invalid device')
+
+ def info(self):
+ if not self.device:
+ return None
+
+ bitmap = ocfs2.Bitmap('abc', 8)
+ return ocfs2.CellMap(bitmap)
Added: trunk/ocfs2tool/browser.py
===================================================================
--- trunk/ocfs2tool/browser.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/browser.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,25 @@
+import gtk
+
+import ocfs2
+
+from guiutil import set_props
+
+class Browser:
+ def __init__(self, device=None, advanced=False):
+ self.widget = gtk.VBox(spacing=4)
+
+ scrl_win = gtk.ScrolledWindow()
+ scrl_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.widget.add(scrl_win)
+
+ tv = gtk.TreeView()
+ scrl_win.add(tv)
+
+ tv.insert_column_with_attributes(-1, 'File', gtk.CellRendererText(),
+ text=0)
+
+ table = gtk.Table(rows=4, columns=2)
+ set_props(table, row_spacing=4,
+ column_spacing=4,
+ border_width=4)
+ self.widget.pack_end(table)
Added: trunk/ocfs2tool/cellmap.defs
===================================================================
--- trunk/ocfs2tool/cellmap.defs 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/cellmap.defs 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,74 @@
+;; -*- scheme -*-
+; object definitions ...
+(define-object Bitmap
+ (in-module "Ocfs")
+ (parent "GObject")
+ (c-name "OcfsBitmap")
+ (gtype-id "OCFS_TYPE_BITMAP")
+)
+
+(define-object CellMap
+ (in-module "Ocfs")
+ (parent "GtkDrawingArea")
+ (c-name "OcfsCellMap")
+ (gtype-id "OCFS_TYPE_CELL_MAP")
+)
+
+;; Enumerations and flags ...
+
+
+;; From ocfsbitmap.h
+
+(define-function ocfs_bitmap_get_type
+ (c-name "ocfs_bitmap_get_type")
+ (return-type "GType")
+)
+
+(define-function ocfs_bitmap_new
+ (c-name "ocfs_bitmap_new")
+ (is-constructor-of "OcfsBitmap")
+ (return-type "OcfsBitmap*")
+ (parameters
+ '("guchar*" "data")
+ '("guint" "len")
+ )
+)
+
+
+
+;; From ocfscellmap.h
+
+(define-function ocfs_cell_map_get_type
+ (c-name "ocfs_cell_map_get_type")
+ (return-type "GType")
+)
+
+(define-function ocfs_cell_map_new
+ (c-name "ocfs_cell_map_new")
+ (is-constructor-of "OcfsCellMap")
+ (return-type "GtkWidget*")
+ (parameters
+ '("OcfsBitmap*" "map")
+ )
+)
+
+(define-method set_map
+ (of-object "OcfsCellMap")
+ (c-name "ocfs_cell_map_set_map")
+ (return-type "none")
+ (parameters
+ '("OcfsBitmap*" "map")
+ )
+)
+
+(define-method set_cell_props
+ (of-object "OcfsCellMap")
+ (c-name "ocfs_cell_map_set_cell_props")
+ (return-type "none")
+ (parameters
+ '("gint" "cell_width")
+ '("gint" "cell_height")
+ )
+)
+
+
Added: trunk/ocfs2tool/cellmap.override
===================================================================
--- trunk/ocfs2tool/cellmap.override 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/cellmap.override 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,16 @@
+%%
+headers
+#include <Python.h>
+
+#define NO_IMPORT_PYGOBJECT
+#include "pygobject.h"
+#include "ocfscellmap.h"
+%%
+modulename ocfs2
+%%
+import gobject.GObject as PyGObject_Type
+import gtk.DrawingArea as PyGtkDrawingArea_Type
+%%
+ignore-glob
+ *_get_type
+%%
Added: trunk/ocfs2tool/format.py
===================================================================
--- trunk/ocfs2tool/format.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/format.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,186 @@
+import gtk
+
+import ocfs2
+
+from guiutil import set_props, error_box, format_bytes
+from process import Process
+
+class BaseCombo(gtk.Combo):
+ def __init__(self):
+ gtk.Combo.__init__(self)
+ self.entry.set_editable(False)
+
+class ValueCombo(BaseCombo):
+ def __init__(self, minimum, maximum):
+ BaseCombo.__init__(self)
+
+ choices = ['Auto']
+
+ size = minimum
+ while size <= maximum:
+ choices.append(format_bytes(size))
+ size = size << 1
+
+ self.set_popdown_strings(choices)
+
+ def get_arg(self):
+ text = self.entry.get_text()
+
+ if text != 'Auto':
+ s = text.replace(' ', '')
+ s = s.replace('B', '')
+ s = s.replace('bytes', '')
+ return (self.arg, s)
+ else:
+ return None
+
+class NumNodes(gtk.SpinButton):
+ def __init__(self):
+ adjustment = gtk.Adjustment(4, 2, ocfs2.MAX_NODES, 1, 10)
+ gtk.SpinButton.__init__(self, adjustment=adjustment, )
+
+ def get_arg(self):
+ s = self.get_text()
+
+ if s:
+ return ('-n', s)
+ else:
+ return None
+
+class Device(BaseCombo):
+ def fill(self, partitions, device):
+ for partition in partitions:
+ item = gtk.ListItem(partition)
+ item.show()
+ self.list.add(item)
+
+ if partition == device:
+ item.select()
+
+ def get_device(self):
+ return self.entry.get_text()
+
+class VolumeLabel(gtk.Entry):
+ def __init__(self):
+ gtk.Entry.__init__(self, max=ocfs2.MAX_VOL_LABEL_LEN)
+ self.set_text('oracle')
+
+ def get_arg(self):
+ s = self.get_text()
+
+ if s:
+ return ('-L', s)
+ else:
+ return None
+
+class ClusterSize(ValueCombo):
+ def __init__(self):
+ ValueCombo.__init__(self, ocfs2.MIN_CLUSTER_SIZE,
+ ocfs2.MAX_CLUSTER_SIZE)
+ self.arg = '-c'
+
+class BlockSize(ValueCombo):
+ def __init__(self):
+ ValueCombo.__init__(self, ocfs2.MIN_BLOCKSIZE,
+ ocfs2.MAX_BLOCKSIZE)
+ self.arg = '-b'
+
+entries = (
+ ('Device', Device, False),
+ ('Volume Label', VolumeLabel, False),
+ ('Cluster Size', ClusterSize, False),
+ ('Number of Nodes', NumNodes, False),
+ ('Block Size', BlockSize, True)
+)
+
+def format_partition(parent, device, advanced):
+ partitions = ocfs2.partition_list(True)
+
+ if not partitions:
+ error_box(parent, 'No unmounted partitions')
+ return False
+
+ if advanced:
+ rows = 5
+ else:
+ rows = 4
+
+ dialog = gtk.Dialog(parent=parent, title='Format',
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OK, gtk.RESPONSE_OK))
+
+ table = gtk.Table(rows=rows, columns=2)
+ set_props(table, row_spacing=4,
+ column_spacing=4,
+ border_width=4,
+ parent=dialog.vbox)
+
+ partitions.sort()
+
+ widgets = []
+ row = 0
+
+ for desc, widget_type, advanced_only in entries:
+ if advanced_only and not advanced:
+ continue
+
+ label = gtk.Label(desc + ':')
+ set_props(label, xalign=1.0)
+ table.attach(label, 0, 1, row, row + 1)
+
+ widget = widget_type()
+ table.attach(widget, 1, 2, row, row + 1)
+
+ if widget_type == Device:
+ widget.fill(partitions, device)
+
+ widgets.append(widget)
+
+ row = row + 1
+
+ widgets[0].grab_focus()
+
+ dialog.show_all()
+
+ if dialog.run() != gtk.RESPONSE_OK:
+ dialog.destroy()
+ return False
+
+ dev = widgets[0].get_device()
+ msg = 'Are you sure you want to format %s?' % dev
+
+ ask = gtk.MessageDialog(parent=dialog,
+ flags=gtk.DIALOG_DESTROY_WITH_PARENT,
+ type=gtk.MESSAGE_QUESTION,
+ buttons=gtk.BUTTONS_YES_NO,
+ message_format=msg)
+
+ if ask.run() != gtk.RESPONSE_YES:
+ dialog.destroy()
+ return False
+
+ command = ['mkfs.ocfs2']
+ for widget in widgets[1:]:
+ arg = widget.get_arg()
+
+ if arg:
+ command.extend(arg)
+
+ command.append(dev)
+
+ dialog.destroy()
+
+ mkfs = Process(command, 'Format', 'Formatting...', parent)
+ success, output, k = mkfs.reap()
+
+ if not success:
+ error_box(parent, 'Format error: %s' % output)
+ return False
+
+ return True
+
+def main():
+ format(None, None, True)
+
+if __name__ == '__main__':
+ main()
Added: trunk/ocfs2tool/general.py
===================================================================
--- trunk/ocfs2tool/general.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/general.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,74 @@
+import gtk
+
+import ocfs2
+
+from guiutil import set_props, format_bytes
+
+fields = (
+ ('Version', 'version'),
+ ('Label', 's_label'),
+ ('UUID', 's_uuid'),
+ ('Maximum Nodes', 's_max_nodes'),
+ ('Cluster Size', 's_clustersize_bits'),
+ ('Block Size', 's_blocksize_bits')
+)
+
+class General:
+ def __init__(self, device=None, advanced=False):
+ self.widget = gtk.Table(rows=5, columns=2)
+
+ set_props(self.widget, row_spacing=4,
+ column_spacing=4,
+ border_width=4)
+
+ super = None
+
+ if device:
+ try:
+ super = ocfs2.get_super(device)
+ except ocfs2.error:
+ pass
+
+ self.pos = 0
+
+ for desc, member in fields:
+ if super:
+ if member == 'version':
+ val = '%d.%d' % super[0:2]
+ else:
+ val = getattr(super, member)
+
+ if member.endswith('_bits'):
+ val = format_bytes(1 << val)
+ else:
+ val = 'N/A'
+
+ self.add_field(desc, val)
+
+ def add_field(self, desc, val):
+ label = gtk.Label(desc + ':')
+ set_props(label, xalign=1.0)
+ self.widget.attach(label, 0, 1, self.pos, self.pos + 1,
+ xoptions=gtk.FILL, yoptions=gtk.FILL)
+
+ label = gtk.Label(str(val))
+ set_props(label, xalign=0.0)
+ self.widget.attach(label, 1, 2, self.pos, self.pos + 1,
+ xoptions=gtk.FILL, yoptions=gtk.FILL)
+
+ self.pos += 1
+
+def main():
+ import sys
+
+ window = gtk.Window()
+
+ general = General(sys.argv[1], False).widget
+ window.add(general)
+
+ window.show_all()
+
+ gtk.main()
+
+if __name__ == '__main__':
+ main()
Added: trunk/ocfs2tool/guiutil.py
===================================================================
--- trunk/ocfs2tool/guiutil.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/guiutil.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,63 @@
+import gtk
+
+def set_props(obj, **kwargs):
+ for k, v in kwargs.items():
+ obj.set_property(k, v)
+
+suffixes = ['K', 'MB', 'GB', 'TB']
+
+def format_bytes(bytes, show_bytes=False):
+ if bytes == 1:
+ return '1 byte'
+ elif bytes < 1024:
+ return str(bytes) + ' bytes'
+
+ fbytes = float(bytes)
+
+ i = -1
+ while i < 3 and fbytes >= 1024:
+ fbytes /= 1024
+ i += 1
+
+ if show_bytes:
+ return '%.1f %s (%sb)' % (fbytes, suffixes[i], bytes)
+ else:
+ return '%.0f %s' % (fbytes, suffixes[i])
+
+def error_box(parent, msg):
+ dialog = gtk.MessageDialog(parent=parent,
+ flags=gtk.DIALOG_DESTROY_WITH_PARENT,
+ type=gtk.MESSAGE_ERROR,
+ buttons=gtk.BUTTONS_OK, message_format=msg)
+ dialog.run()
+ dialog.destroy()
+
+def query_text(parent, prompt):
+ dialog = gtk.Dialog(parent=parent,
+ flags=gtk.DIALOG_DESTROY_WITH_PARENT,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OK, gtk.RESPONSE_OK))
+
+ table = gtk.Table(rows=1, columns=2)
+ set_props(table, row_spacing=4,
+ column_spacing=4,
+ border_width=4,
+ parent=dialog.vbox)
+
+ label = gtk.Label(prompt + ':')
+ set_props(label, xalign=1.0)
+ table.attach(label, 0, 1, 0, 1)
+
+ entry = gtk.Entry()
+ table.attach(entry, 1, 2, 0, 1)
+
+ dialog.show_all()
+
+ if dialog.run() == gtk.RESPONSE_OK:
+ text = entry.get_text()
+ else:
+ text = None
+
+ dialog.destroy()
+
+ return text
Added: trunk/ocfs2tool/main.py
===================================================================
--- trunk/ocfs2tool/main.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/main.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,337 @@
+#!/usr/bin/python
+
+import sys
+
+import gtk
+
+import ocfs2
+
+from guiutil import set_props, error_box, query_text
+from process import Process
+from format import format_partition
+from general import General
+from nodemap import NodeMap
+from bitmap import Bitmap
+from browser import Browser
+
+OCFS2TOOL_VERSION = '0.0.1'
+
+COLUMN_DEVICE = 0
+COLUMN_MOUNTPOINT = 1
+COLUMN_TYPE = 2
+
+MODE_BASIC = 0
+MODE_ADVANCED = 1
+
+notebook_items = (
+ ('general', 'General', General),
+ ('browser', 'File Listing', Browser),
+ ('nodemap', 'Configured Nodes', NodeMap),
+ ('bitmap', 'Bitmap View', Bitmap),
+)
+
+def cleanup(*args):
+ gtk.main_quit()
+
+def usage(name):
+ print '''Usage: %s [OPTION]...
+Options:
+ -V, --version print version information and exit
+ --help display this help and exit''' % name
+
+class PartitionView(gtk.TreeView):
+ def __init__(self, toplevel):
+ store = gtk.ListStore(str, str, str)
+
+ gtk.TreeView.__init__(self, store)
+
+ self.toplevel = toplevel
+ self.advanced = MODE_BASIC
+
+ self.insert_column_with_attributes(-1, 'Device',
+ gtk.CellRendererText(),
+ text=COLUMN_DEVICE)
+ self.insert_column_with_attributes(-1, 'Type',
+ gtk.CellRendererText(),
+ text=COLUMN_TYPE)
+ self.insert_column_with_attributes(-1, 'Mountpoint',
+ gtk.CellRendererText(),
+ text=COLUMN_MOUNTPOINT)
+
+ sel = self.get_selection()
+ sel.connect('changed', self.on_select)
+
+ def get_sel_values(self):
+ sel = self.get_selection()
+ store, iter = sel.get_selected()
+
+ if store and iter:
+ return store[iter]
+ else:
+ return None
+
+ def get_device(self):
+ selection = self.get_sel_values()
+
+ if selection:
+ return selection[COLUMN_DEVICE]
+ else:
+ return None
+
+ def on_select(self, sel):
+ device, mountpoint, type = self.get_sel_values()
+
+ if mountpoint:
+ self.mount_button.set_sensitive(False)
+ self.unmount_button.set_sensitive(True)
+ else:
+ self.mount_button.set_sensitive(True)
+ self.unmount_button.set_sensitive(False)
+
+ update_notebook(self, device)
+
+ def select_device(self, device):
+ for row in self.get_model():
+ if row[COLUMN_DEVICE] == device:
+ sel = self.get_selection()
+ sel.select_iter(row.iter)
+
+ def refresh_partitions(self):
+ def list_compare(store, a, b):
+ d1, m1, t1 = store[a]
+ d2, m2, t1 = store[b]
+
+ if m1 and not m2:
+ return -1
+ elif not m1 and m2:
+ return 1
+ else:
+ return cmp(d1, d2)
+
+ self.mount_button.set_sensitive(False)
+ self.unmount_button.set_sensitive(False)
+
+ old_device = self.get_device()
+
+ store = gtk.ListStore(str, str, str)
+ self.set_model(store)
+
+ sel = self.get_selection()
+ selected = False
+
+ for partition in ocfs2.partition_list():
+ iter = store.append(partition)
+
+ if partition[0] == old_device:
+ sel.select_iter(iter)
+ selected = True
+
+ store.set_sort_func(COLUMN_DEVICE, list_compare)
+ store.set_sort_column_id(COLUMN_DEVICE, gtk.SORT_ASCENDING)
+
+ if len(store) and not selected:
+ sel.select_iter(store.get_iter_first())
+
+def mount(button, pv):
+ device, mountpoint, type = pv.get_sel_values()
+
+ mountpoint = query_text(pv.toplevel, 'Mountpoint')
+ if not mountpoint:
+ return
+
+ command = ('mount', '-t', type, device, mountpoint)
+
+ p = Process(command, 'Mount', 'Mounting...', pv.toplevel, spin_now=False)
+ success, output, killed = p.reap()
+
+ if not success:
+ if killed:
+ error_box(pv.toplevel,
+ 'mount died unexpectedly! Your system is probably in '
+ 'an inconsistent state. You should reboot at the '
+ 'earliest opportunity')
+ else:
+ error_box(pv.toplevel, '%s: Could not mount %s' % (output, device))
+
+ pv.refresh_partitions()
+
+def unmount(button, pv):
+ device, mountpoint, type = pv.get_sel_values()
+
+ command = ('umount', mountpoint)
+
+ p = Process(command, 'Unmount', 'Unmounting...', pv.toplevel,
+ spin_now=False)
+ success, output, killed = p.reap()
+
+ if success:
+ pv.refresh_partitions()
+ else:
+ if killed:
+ error_box(pv.toplevel,
+ 'umount died unexpectedly! Your system is probably in '
+ 'an inconsistent state. You should reboot at the '
+ 'earliest opportunity')
+ else:
+ error_box(pv.toplevel,
+ '%s: Could not unmount %s mounted on %s' %
+ (output, device, mountpoint))
+
+def refresh(button, pv):
+ pv.refresh_partitions()
+
+ if len(pv.get_model()) == 0:
+ update_notebook(pv, None)
+
+def update_notebook(pv, device):
+ for tag, d, info in notebook_items:
+ frame = getattr(pv, tag + '-frame')
+ frame.child.destroy()
+
+ frame.add(info(device, pv.advanced).widget)
+ frame.show_all()
+
+def create_action_area(pv):
+ vbbox = gtk.VButtonBox()
+ set_props(vbbox, layout_style=gtk.BUTTONBOX_START,
+ spacing=5,
+ border_width=5)
+
+ button = gtk.Button("Mount")
+ vbbox.add(button)
+ button.connect('clicked', mount, pv)
+ pv.mount_button = button
+
+ button = gtk.Button("Unmount")
+ vbbox.add(button)
+ button.connect('clicked', unmount, pv)
+ pv.unmount_button = button
+
+ button = gtk.Button("Refresh")
+ vbbox.add(button)
+ button.connect('clicked', refresh, pv)
+
+ return vbbox
+
+def format(pv, action, w):
+ format_partition(pv.toplevel, pv.get_device(), pv.advanced)
+ pv.refresh_partitions()
+
+def genconfig(pv, action, w):
+ pass
+
+def level(pv, action, w):
+ if pv.advanced == action:
+ return
+
+ pv.advanced = action
+
+def about(pv, a, w):
+ dialog = gtk.MessageDialog(parent=pv.toplevel,
+ flags=gtk.DIALOG_DESTROY_WITH_PARENT,
+ buttons=gtk.BUTTONS_CLOSE)
+ dialog.label.set_text('''OCFS2 Tool
+Version %s
+Copyright (C) Oracle Corporation 2002, 2004
+All Rights Reserved''' % OCFS2TOOL_VERSION)
+
+ dialog.run()
+ dialog.destroy()
+
+menu_items = (
+ ('/_File', None, None, 0, '<Branch>'),
+ ('/File/_Quit', None, cleanup, 0, '<StockItem>', gtk.STOCK_QUIT),
+ ('/_Tasks', None, None, 0, '<Branch>'),
+ ('/Tasks/_Format...', '<control>F', format, 0),
+ #('/Tasks/---', None, None, 0, '<Separator>'),
+ #('/Tasks/_Generate Config...', '<control>G', genconfig, 0),
+ ('/_Preferences', None, None, 0, '<Branch>'),
+ ('/Preferences/_Basic', '<control>B', level, MODE_BASIC, '<RadioItem>'),
+ ('/Preferences/_Advanced', '<control>A', level, MODE_ADVANCED, '/Preferences/Basic'),
+ ('/_Help', None, None, 0, '<Branch>'),
+ ('/Help/_About', None, about, 0)
+)
+
+def create_window():
+ window = gtk.Window()
+ set_props(window, title='OCFS2 Tool',
+ default_width=520,
+ default_height=420,
+ border_width=0)
+ window.connect('delete_event', cleanup)
+
+ pv = PartitionView(window)
+
+ accel_group = gtk.AccelGroup()
+ window.add_accel_group(accel_group)
+
+ item_factory = gtk.ItemFactory(gtk.MenuBar, '<main>', accel_group)
+ item_factory.create_items(menu_items, pv)
+ window.item_factory = item_factory
+
+ vbox = gtk.VBox()
+ window.add(vbox)
+
+ menubar = item_factory.get_widget('<main>')
+ vbox.pack_start(menubar, expand=False, fill=False)
+
+ vpaned = gtk.VPaned()
+ vpaned.set_border_width(4)
+ vbox.pack_start(vpaned, expand=True, fill=True)
+
+ hbox = gtk.HBox()
+ vpaned.pack1(hbox)
+
+ scrl_win = gtk.ScrolledWindow()
+ set_props(scrl_win, hscrollbar_policy=gtk.POLICY_AUTOMATIC,
+ vscrollbar_policy=gtk.POLICY_AUTOMATIC,
+ parent=hbox)
+
+ scrl_win.add(pv)
+
+ frame = gtk.Frame()
+ frame.set_shadow_type(gtk.SHADOW_IN)
+ hbox.pack_end(frame, expand=False, fill=False)
+
+ vbbox = create_action_area(pv)
+ frame.add(vbbox)
+
+ notebook = gtk.Notebook()
+ notebook.set_tab_pos(gtk.POS_TOP)
+ vpaned.pack2(notebook)
+
+ for tag, desc, info in notebook_items:
+ frame = gtk.Frame()
+ set_props(frame, shadow=gtk.SHADOW_NONE,
+ border_width=0)
+
+ tag = tag + '-frame'
+ setattr(pv, tag, frame)
+
+ frame.add(info().widget)
+ frame.show_all()
+
+ notebook.add_with_properties(frame, 'tab_label', desc)
+
+ pv.refresh_partitions()
+
+ window.show_all()
+
+def main():
+ for arg in sys.argv[1:]:
+ if arg == '--version' or arg == '-V':
+ print 'OCFS2Tool version %s' % OCFS2TOOL_VERSION
+ sys.exit(0)
+ elif arg == '--help':
+ usage(sys.argv[0])
+ sys.exit(0)
+ else:
+ usage(sys.argv[0])
+ sys.exit(1)
+
+ create_window()
+
+ gtk.main()
+
+if __name__ == '__main__':
+ main()
Property changes on: trunk/ocfs2tool/main.py
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/ocfs2tool/nodemap.py
===================================================================
--- trunk/ocfs2tool/nodemap.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/nodemap.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,65 @@
+import gtk
+
+import ocfs2
+
+COLUMN_SLOT = 0
+COLUMN_NAME = 1
+COLUMN_IP = 2
+COLUMN_PORT = 3
+COLUMN_UUID = 4
+
+class NodeMap:
+ def __init__(self, device=None, advanced=False):
+ self.device = device
+ self.advanced = advanced
+
+ info = self.info()
+
+ if info:
+ self.widget = gtk.ScrolledWindow()
+ self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ self.widget.add(info)
+ else:
+ self.widget = gtk.Label('Invalid device')
+
+ def info(self):
+ if not self.device:
+ return None
+
+ store = gtk.ListStore(int, str, str, int, str)
+
+ tv = gtk.TreeView(store)
+
+ tv.insert_column_with_attributes(-1, 'Slot #',
+ gtk.CellRendererText(),
+ text=COLUMN_SLOT)
+ tv.insert_column_with_attributes(-1, 'Node Name',
+ gtk.CellRendererText(),
+ text=COLUMN_NAME)
+ tv.insert_column_with_attributes(-1, 'IP Address',
+ gtk.CellRendererText(),
+ text=COLUMN_IP)
+ tv.insert_column_with_attributes(-1, 'Port',
+ gtk.CellRendererText(),
+ text=COLUMN_PORT)
+
+ if self.advanced:
+ tv.insert_column_with_attributes(-1, 'UUID',
+ gtk.CellRendererText(),
+ text=COLUMN_UUID)
+
+ return tv
+def main():
+ import sys
+
+ window = gtk.Window()
+ window.show()
+
+ nodemap = NodeMap(sys.argv[1], False).widget
+ window.add(nodemap)
+
+ window.show_all()
+ gtk.main()
+
+if __name__ == '__main__':
+ main()
Added: trunk/ocfs2tool/ocfs2module.c
===================================================================
--- trunk/ocfs2tool/ocfs2module.c 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/ocfs2module.c 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,248 @@
+/*
+ * ocfs2module.c
+ *
+ * OCFS2 python binding.
+ *
+ * Copyright (C) 2004 Oracle. All rights reserved.
+ *
+ * Author: Manish Singh <manish.singh at oracle.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 recieved a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <glib.h>
+
+#include <pygobject.h>
+#include <pygtk/pygtk.h>
+
+#include "ocfs2.h"
+
+#include "ocfsplist.h"
+
+
+#define MAX_CLUSTER_SIZE 1048576
+#define MIN_CLUSTER_SIZE 4096
+
+
+void cellmap_register_classes (PyObject *d);
+extern PyMethodDef cellmap_functions[];
+
+
+static PyObject *ocfs2_error;
+
+static PyObject *
+partition_list (PyObject *self,
+ PyObject *args)
+{
+ gboolean unmounted = FALSE, bail = FALSE;
+ GList *list, *last;
+ PyObject *ret, *val;
+ OcfsPartitionInfo *info;
+
+ if (!PyArg_ParseTuple (args, "|i:partition_list", &unmounted))
+ return NULL;
+
+ list = ocfs_partition_list (unmounted);
+
+ ret = PyList_New (0);
+ if (ret == NULL)
+ bail = TRUE;
+
+ while (list)
+ {
+
+ if (!bail)
+ {
+ if (!unmounted)
+ {
+ info = list->data;
+ val = Py_BuildValue ("(sss)",
+ info->device, info->mountpoint,
+ info->type == OCFS_FS_TYPE_OCFS2 ? "ocfs2"
+ : "ocfs");
+ }
+ else
+ val = PyString_FromString (list->data);
+
+ if (val)
+ {
+ PyList_Append (ret, val);
+ Py_DECREF (val);
+ }
+ else
+ bail = TRUE;
+ }
+
+ if (!unmounted)
+ {
+ g_free (info->device);
+ g_free (info->mountpoint);
+ g_free (info);
+ }
+ else
+ g_free (list->data);
+
+ last = list;
+ list = list->next;
+
+ g_list_free_1 (last);
+ }
+
+ if (bail)
+ {
+ Py_XDECREF (ret);
+ return NULL;
+ }
+ else
+ return ret;
+}
+
+static PyStructSequence_Field struct_ocfs2_super_fields[] = {
+ {"s_major_rev_level", "major revision level"},
+ {"s_minor_rev_level", "minor revision level"},
+ {"s_blocksize_bits", "blocksize bits"},
+ {"s_clustersize_bits", "cluster size bits"},
+ {"s_max_nodes", "maximum nodes"},
+ {"s_label", "volume label"},
+ {"s_uuid", "UUID"},
+ {0}
+};
+
+struct PyStructSequence_Desc struct_ocfs2_super_desc = {
+ "ocfs2.struct_ocfs2_super",
+ NULL,
+ struct_ocfs2_super_fields,
+ 7,
+};
+
+static PyTypeObject StructOcfs2SuperType;
+
+static PyObject *
+get_super (PyObject *self,
+ PyObject *args)
+{
+ gchar *device;
+ errcode_t ret;
+ ocfs2_filesys *fs;
+ PyObject *v;
+ gint index = 0;
+ GString *uuid;
+ gint i;
+
+ if (!PyArg_ParseTuple (args, "s:get_super", &device))
+ return NULL;
+
+ ret = ocfs2_open (device, OCFS2_FLAG_RO, 0, 0, &fs);
+ if (ret)
+ {
+ PyErr_SetString (ocfs2_error, error_message (ret));
+ return NULL;
+ }
+
+ v = PyStructSequence_New (&StructOcfs2SuperType);
+ if (v == NULL)
+ return NULL;
+
+#define SET(m) \
+ PyStructSequence_SET_ITEM (v, index++, PyInt_FromLong \
+ (OCFS2_RAW_SB (fs->fs_super)->m));
+
+ SET (s_major_rev_level);
+ SET (s_minor_rev_level);
+ SET (s_blocksize_bits);
+ SET (s_clustersize_bits);
+ SET (s_max_nodes);
+
+#undef SET
+#define SET(m) \
+ PyStructSequence_SET_ITEM \
+ (v, index++, PyString_FromString (OCFS2_RAW_SB (fs->fs_super)->m));
+
+ PyStructSequence_SET_ITEM
+ (v, index++, PyString_FromString (OCFS2_RAW_SB (fs->fs_super)->s_label));
+
+#undef SET
+
+ uuid = g_string_sized_new (32);
+
+ for (i = 0; i < 16; i++)
+ g_string_append_printf (uuid, "%02X",
+ OCFS2_RAW_SB (fs->fs_super)->s_uuid[i]);
+
+ PyStructSequence_SET_ITEM (v, index++, PyString_FromString (uuid->str));
+
+ g_string_free (uuid, TRUE);
+
+ ocfs2_close (fs);
+
+ if (PyErr_Occurred())
+ {
+ Py_DECREF (v);
+ return NULL;
+ }
+
+ return v;
+}
+
+static PyMethodDef ocfs2_methods[] = {
+ {"partition_list", partition_list, METH_VARARGS},
+ {"get_super", get_super, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+void
+initocfs2 (void)
+{
+ PyObject *m, *d;
+
+ init_pygobject ();
+ init_pygtk ();
+
+ initialize_ocfs_error_table ();
+
+ m = Py_InitModule ("ocfs2", ocfs2_methods);
+
+ PyStructSequence_InitType (&StructOcfs2SuperType, &struct_ocfs2_super_desc);
+ Py_INCREF (&StructOcfs2SuperType);
+ PyModule_AddObject (m, "struct_ocfs2_super",
+ (PyObject *) &StructOcfs2SuperType);
+
+ ocfs2_error = PyErr_NewException ("ocfs2.error", PyExc_RuntimeError, NULL);
+ if (ocfs2_error)
+ {
+ Py_INCREF (ocfs2_error);
+ PyModule_AddObject (m, "error", ocfs2_error);
+ }
+
+ PyModule_AddIntConstant (m, "MAX_VOL_LABEL_LEN", MAX_VOL_LABEL_LEN);
+ PyModule_AddIntConstant (m, "MAX_NODES", OCFS2_MAX_NODES);
+
+ PyModule_AddIntConstant (m, "MIN_BLOCKSIZE", OCFS2_MIN_BLOCKSIZE);
+ PyModule_AddIntConstant (m, "MAX_BLOCKSIZE", OCFS2_MAX_BLOCKSIZE);
+
+ PyModule_AddIntConstant (m, "MIN_CLUSTER_SIZE", MIN_CLUSTER_SIZE);
+ PyModule_AddIntConstant (m, "MAX_CLUSTER_SIZE", MAX_CLUSTER_SIZE);
+
+ d = PyModule_GetDict (m);
+
+ cellmap_register_classes (d);
+
+ if (PyErr_Occurred ())
+ Py_FatalError ("can't initialise module ocfs2");
+}
Added: trunk/ocfs2tool/ocfs2tool
===================================================================
--- trunk/ocfs2tool/ocfs2tool 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/ocfs2tool 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,6 @@
+#!/usr/bin/python
+
+from main import main
+
+if __name__ == '__main__':
+ main()
Property changes on: trunk/ocfs2tool/ocfs2tool
___________________________________________________________________
Name: svn:executable
+ *
Copied: trunk/ocfs2tool/ocfs2tool.8.in (from rev 259, trunk/ocfstool/ocfstool.8.in)
Added: trunk/ocfs2tool/ocfsbitmap.c
===================================================================
--- trunk/ocfs2tool/ocfsbitmap.c 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/ocfsbitmap.c 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,107 @@
+/*
+ * ocfsbitmap.c
+ *
+ * A simple object containing a bitmap
+ *
+ * Copyright (C) 2004 Oracle Corporation. All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Manish Singh
+ */
+
+#include <glib-object.h>
+
+#include "ocfsbitmap.h"
+
+
+static void ocfs_bitmap_class_init (OcfsBitmapClass *class);
+static void ocfs_bitmap_init (OcfsBitmap *bitmap);
+static void ocfs_bitmap_finalize (GObject *object);
+
+
+static GObjectClass *parent_class = NULL;
+
+
+GType
+ocfs_bitmap_get_type (void)
+{
+ static GType bitmap_type = 0;
+
+ if (! bitmap_type)
+ {
+ static const GTypeInfo bitmap_info =
+ {
+ sizeof (OcfsBitmapClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ocfs_bitmap_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (OcfsBitmap),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ocfs_bitmap_init,
+ };
+
+ bitmap_type = g_type_register_static (G_TYPE_OBJECT, "OcfsBitmap",
+ &bitmap_info, 0);
+ }
+
+ return bitmap_type;
+}
+
+static void
+ocfs_bitmap_class_init (OcfsBitmapClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = ocfs_bitmap_finalize;
+}
+
+static void
+ocfs_bitmap_init (OcfsBitmap *bitmap)
+{
+ bitmap->data = NULL;
+ bitmap->len = 0;
+}
+
+static void
+ocfs_bitmap_finalize (GObject *object)
+{
+ OcfsBitmap *bitmap = OCFS_BITMAP (object);
+
+ g_free (bitmap->data);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+OcfsBitmap *
+ocfs_bitmap_new (guchar *data,
+ guint len)
+{
+ OcfsBitmap *bitmap;
+
+ bitmap = g_object_new (OCFS_TYPE_BITMAP, NULL);
+
+ bitmap->data = data;
+ bitmap->len = len;
+
+ return bitmap;
+}
Added: trunk/ocfs2tool/ocfsbitmap.h
===================================================================
--- trunk/ocfs2tool/ocfsbitmap.h 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/ocfsbitmap.h 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,63 @@
+/*
+ * ocfsbitmap.h
+ *
+ * Function prototypes for related 'C' file.
+ *
+ * Copyright (C) 2004 Oracle Corporation. All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Manish Singh
+ */
+
+#ifndef __OCFS_BITMAP_H__
+#define __OCFS_BITMAP_H__
+
+
+#include <glib-object.h>
+
+
+#define OCFS_TYPE_BITMAP (ocfs_bitmap_get_type ())
+#define OCFS_BITMAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OCFS_TYPE_BITMAP, OcfsBitmap))
+#define OCFS_BITMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OCFS_TYPE_BITMAP, OcfsBitmapClass))
+#define OCFS_IS_BITMAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OCFS_TYPE_BITMAP))
+#define OCFS_IS_BITMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OCFS_TYPE_BITMAP))
+#define OCFS_BITMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OCFS_TYPE_BITMAP, OcfsBitmapCLass))
+
+
+typedef struct _OcfsBitmap OcfsBitmap;
+typedef struct _OcfsBitmapClass OcfsBitmapClass;
+
+struct _OcfsBitmap
+{
+ GObject parent_instance;
+
+ guchar *data;
+ guint len;
+};
+
+struct _OcfsBitmapClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType ocfs_bitmap_get_type (void);
+OcfsBitmap *ocfs_bitmap_new (guchar *data,
+ guint len);
+
+
+#endif /* __OCFS_BITMAP_H__ */
Copied: trunk/ocfs2tool/ocfscellmap.c (from rev 256, trunk/ocfstool/ocfscellmap.c)
===================================================================
--- trunk/ocfstool/ocfscellmap.c 2004-09-24 23:55:36 UTC (rev 256)
+++ trunk/ocfs2tool/ocfscellmap.c 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,646 @@
+/*
+ * ocfscellmap.c
+ *
+ * A scrollable bitmap display widget
+ *
+ * Copyright (C) 2002 Oracle Corporation. All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Manish Singh
+ */
+
+#include <gtk/gtk.h>
+
+#include "ocfscellmap.h"
+
+#include "ocfsmarshal.h"
+
+
+#define DEFAULT_CELL_WIDTH 10
+#define DEFAULT_CELL_HEIGHT 10
+
+#define CELL_MAP_MASK (GDK_EXPOSURE_MASK | \
+ GDK_POINTER_MOTION_MASK | \
+ GDK_POINTER_MOTION_HINT_MASK | \
+ GDK_ENTER_NOTIFY_MASK | \
+ GDK_BUTTON_PRESS_MASK | \
+ GDK_BUTTON_RELEASE_MASK | \
+ GDK_BUTTON1_MOTION_MASK)
+
+
+enum {
+ PROP_0,
+ PROP_MAP,
+ PROP_CELL_WIDTH,
+ PROP_CELL_HEIGHT,
+ PROP_HADJUSTMENT,
+ PROP_VADJUSTMENT
+};
+
+
+static void ocfs_cell_map_class_init (OcfsCellMapClass *class);
+static void ocfs_cell_map_init (OcfsCellMap *cell_map);
+static void ocfs_cell_map_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ocfs_cell_map_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void ocfs_cell_map_finalize (GObject *object);
+static void ocfs_cell_map_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void paint_cell_map (GtkWidget *widget);
+static void ocfs_cell_map_state_changed (GtkWidget *widget,
+ GtkStateType old_state);
+static gboolean ocfs_cell_map_configure (GtkWidget *widget,
+ GdkEventConfigure *event);
+static gboolean ocfs_cell_map_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static gboolean ocfs_cell_map_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean ocfs_cell_map_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean ocfs_cell_map_motion_notify (GtkWidget *widget,
+ GdkEventMotion *event);
+static void ocfs_cell_map_set_adjustments (OcfsCellMap *cell_map,
+ GtkAdjustment *hadj,
+ GtkAdjustment *vadj);
+static void update_adjustment (GtkAdjustment *adj,
+ OcfsCellMap *cell_map);
+static void compute_vertical_scroll (OcfsCellMap *cell_map);
+
+
+static GtkDrawingAreaClass *parent_class = NULL;
+
+
+GType
+ocfs_cell_map_get_type (void)
+{
+ static GType cell_map_type = 0;
+
+ if (! cell_map_type)
+ {
+ static const GTypeInfo cell_map_info =
+ {
+ sizeof (OcfsCellMapClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ocfs_cell_map_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (OcfsCellMap),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ocfs_cell_map_init,
+ };
+
+ cell_map_type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
+ "OcfsCellMap",
+ &cell_map_info, 0);
+ }
+
+ return cell_map_type;
+}
+
+static void
+ocfs_cell_map_class_init (OcfsCellMapClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = (GObjectClass *) class;
+ widget_class = (GtkWidgetClass *) class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->set_property = ocfs_cell_map_set_property;
+ object_class->get_property = ocfs_cell_map_get_property;
+ object_class->finalize = ocfs_cell_map_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_MAP,
+ g_param_spec_object ("map",
+ "Map",
+ "The cell bitmap",
+ OCFS_TYPE_BITMAP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_CELL_WIDTH,
+ g_param_spec_int ("cell_width",
+ "Cell Width",
+ "The width of each cell in pixels",
+ -1,
+ G_MAXINT,
+ DEFAULT_CELL_WIDTH,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_CELL_HEIGHT,
+ g_param_spec_int ("cell_height",
+ "Cell Height",
+ "The height of each cell in pixels",
+ -1,
+ G_MAXINT,
+ DEFAULT_CELL_HEIGHT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_HADJUSTMENT,
+ g_param_spec_object ("hadjustment",
+ "Horizontal Adjustment",
+ "The GtkAdjustment for the horizontal position",
+ GTK_TYPE_ADJUSTMENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (object_class,
+ PROP_VADJUSTMENT,
+ g_param_spec_object ("vadjustment",
+ "Vertical Adjustment",
+ "The GtkAdjustment for the vertical position",
+ GTK_TYPE_ADJUSTMENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ widget_class->state_changed = ocfs_cell_map_state_changed;
+ widget_class->size_request = ocfs_cell_map_size_request;
+ widget_class->configure_event = ocfs_cell_map_configure;
+ widget_class->expose_event = ocfs_cell_map_expose;
+
+ widget_class->button_press_event = ocfs_cell_map_button_press;
+ widget_class->button_release_event = ocfs_cell_map_button_release;
+ widget_class->motion_notify_event = ocfs_cell_map_motion_notify;
+
+ widget_class->set_scroll_adjustments_signal =
+ g_signal_new ("set_scroll_adjustments",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (OcfsCellMapClass, set_scroll_adjustments),
+ NULL, NULL,
+ _ocfs_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_ADJUSTMENT,
+ GTK_TYPE_ADJUSTMENT);
+
+ class->set_scroll_adjustments = ocfs_cell_map_set_adjustments;
+}
+
+static void
+ocfs_cell_map_init (OcfsCellMap *cell_map)
+{
+ gint old_mask;
+
+ cell_map->map = NULL;
+
+ cell_map->cell_width = DEFAULT_CELL_WIDTH;
+ cell_map->cell_height = DEFAULT_CELL_HEIGHT;
+
+ cell_map->hadj = NULL;
+ cell_map->vadj = NULL;
+
+ old_mask = gtk_widget_get_events (GTK_WIDGET (cell_map));
+ gtk_widget_set_events (GTK_WIDGET (cell_map), old_mask | CELL_MAP_MASK);
+}
+
+static void
+ocfs_cell_map_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OcfsCellMap *cell_map = OCFS_CELL_MAP (object);
+
+ switch (property_id)
+ {
+ case PROP_MAP:
+ ocfs_cell_map_set_map (cell_map, g_value_get_object (value));
+ break;
+ case PROP_CELL_WIDTH:
+ cell_map->cell_width = g_value_get_int (value);
+ break;
+ case PROP_CELL_HEIGHT:
+ cell_map->cell_height = g_value_get_int (value);
+ break;
+ case PROP_HADJUSTMENT:
+ ocfs_cell_map_set_adjustments (cell_map, g_value_get_object (value),
+ cell_map->vadj);
+ break;
+ case PROP_VADJUSTMENT:
+ ocfs_cell_map_set_adjustments (cell_map, cell_map->hadj,
+ g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ocfs_cell_map_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+
+{
+ OcfsCellMap *cell_map = OCFS_CELL_MAP (object);
+
+ switch (property_id)
+ {
+ case PROP_MAP:
+ g_value_set_object (value, cell_map->map);
+ break;
+ case PROP_CELL_WIDTH:
+ g_value_set_int (value, cell_map->cell_width);
+ break;
+ case PROP_CELL_HEIGHT:
+ g_value_set_int (value, cell_map->cell_height);
+ break;
+ case PROP_HADJUSTMENT:
+ g_value_set_object (value, cell_map->hadj);
+ break;
+ case PROP_VADJUSTMENT:
+ g_value_set_object (value, cell_map->vadj);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+ocfs_cell_map_finalize (GObject *object)
+{
+ OcfsCellMap *cell_map = OCFS_CELL_MAP (object);
+
+ g_object_unref (cell_map->hadj);
+ g_object_unref (cell_map->vadj);
+
+ if (cell_map->map)
+ g_object_unref (cell_map->map);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+GtkWidget *
+ocfs_cell_map_new (OcfsBitmap *map)
+{
+ return g_object_new (OCFS_TYPE_CELL_MAP,
+ "map", map,
+ NULL);
+}
+
+void
+ocfs_cell_map_set_map (OcfsCellMap *cell_map,
+ OcfsBitmap *map)
+{
+ g_return_if_fail (OCFS_IS_CELL_MAP (cell_map));
+
+ if (cell_map->map)
+ g_object_unref (cell_map->map);
+
+ cell_map->map = g_object_ref (map);
+ g_object_notify (G_OBJECT (cell_map), "map");
+
+ gtk_widget_queue_draw (GTK_WIDGET (cell_map));
+}
+
+void
+ocfs_cell_map_set_cell_props (OcfsCellMap *cell_map,
+ gint cell_width,
+ gint cell_height)
+{
+ g_return_if_fail (OCFS_IS_CELL_MAP (cell_map));
+
+#define SET_PROP(prop, def) G_STMT_START { \
+ if (prop > -1) \
+ cell_map->prop = prop; \
+ else if (prop == -1) \
+ cell_map->prop = def; } G_STMT_END
+
+ SET_PROP (cell_width, DEFAULT_CELL_WIDTH);
+ SET_PROP (cell_height, DEFAULT_CELL_HEIGHT);
+
+#undef SET_PROP
+
+ compute_vertical_scroll (cell_map);
+}
+
+static void
+ocfs_cell_map_state_changed (GtkWidget *widget,
+ GtkStateType old_state)
+{
+ gtk_widget_queue_draw (widget);
+}
+
+static void
+ocfs_cell_map_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ OcfsCellMap *cell_map = OCFS_CELL_MAP (widget);
+
+ requisition->width = cell_map->cell_width;
+ requisition->height = cell_map->cell_height;
+}
+
+static void
+paint_cell_map (GtkWidget *widget)
+{
+ OcfsCellMap *cell_map = OCFS_CELL_MAP (widget);
+ GtkStateType state, type;
+ gint i;
+ gint width, height;
+ gint dx, dy;
+ gint per_row;
+ gint start, end;
+ gint val;
+
+ gtk_paint_flat_box (widget->style,
+ widget->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+ NULL, widget, "cell_map_bg",
+ 0, 0,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ if (cell_map && cell_map->map->len)
+ {
+ width = widget->allocation.width - 1;
+ height = widget->allocation.height - 1;
+
+ per_row = width / cell_map->cell_width;
+ per_row = MAX (1, per_row);
+
+ val = cell_map->vadj->value;
+
+ start = val / cell_map->cell_height * per_row;
+ end = height / cell_map->cell_height * per_row + start;
+ end = MIN (end, cell_map->map->len);
+
+ if (end != cell_map->map->len && end + per_row > cell_map->map->len)
+ {
+ if (val % cell_map->cell_height)
+ {
+ start += per_row;
+ end = cell_map->map->len;
+ }
+ }
+
+ state = GTK_STATE_NORMAL;
+ if (!GTK_WIDGET_IS_SENSITIVE (widget))
+ state = GTK_STATE_INSENSITIVE;
+
+ for (i = start; i < end; i++)
+ {
+ dx = (i % per_row) * cell_map->cell_width;
+ dy = ((i - start) / per_row) * cell_map->cell_height;
+
+ type = cell_map->map->data[i] ? GTK_STATE_SELECTED
+ : state;
+
+ gdk_draw_rectangle (widget->window,
+ widget->style->fg_gc[state],
+ FALSE,
+ dx, dy,
+ cell_map->cell_width,
+ cell_map->cell_height);
+
+ gdk_draw_rectangle (widget->window,
+ widget->style->bg_gc[type],
+ TRUE,
+ dx + 1, dy + 1,
+ cell_map->cell_width - 1,
+ cell_map->cell_height - 1);
+ }
+ }
+}
+
+static gboolean
+ocfs_cell_map_configure (GtkWidget *widget,
+ GdkEventConfigure *event)
+{
+ OcfsCellMap *cell_map = OCFS_CELL_MAP (widget);
+
+ compute_vertical_scroll (cell_map);
+
+ return FALSE;
+}
+
+static gboolean
+ocfs_cell_map_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ if (GTK_WIDGET_DRAWABLE (widget))
+ paint_cell_map (widget);
+
+ return FALSE;
+}
+
+static gboolean
+ocfs_cell_map_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ return FALSE;
+}
+
+static gboolean
+ocfs_cell_map_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ return FALSE;
+}
+
+static gboolean
+ocfs_cell_map_motion_notify (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ return FALSE;
+}
+
+static void
+ocfs_cell_map_set_adjustments (OcfsCellMap *cell_map,
+ GtkAdjustment *hadj,
+ GtkAdjustment *vadj)
+{
+ if (hadj)
+ g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
+ else
+ hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+
+ if (vadj)
+ g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
+ else
+ vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+
+ if (cell_map->hadj && (cell_map->hadj != hadj))
+ {
+ g_signal_handlers_disconnect_by_func (GTK_OBJECT (cell_map->hadj),
+ update_adjustment, cell_map);
+ g_object_unref (cell_map->hadj);
+ }
+
+ if (cell_map->vadj && (cell_map->vadj != vadj))
+ {
+ g_signal_handlers_disconnect_by_func (GTK_OBJECT (cell_map->vadj),
+ update_adjustment, cell_map);
+ g_object_unref (cell_map->vadj);
+ }
+
+ if (cell_map->hadj != hadj)
+ {
+ cell_map->hadj = hadj;
+ g_object_ref (cell_map->hadj);
+ gtk_object_sink (GTK_OBJECT (cell_map->hadj));
+
+ g_signal_connect (cell_map->hadj, "changed",
+ G_CALLBACK (update_adjustment), cell_map);
+ g_signal_connect (cell_map->hadj, "value_changed",
+ G_CALLBACK (update_adjustment), cell_map);
+
+ update_adjustment (hadj, cell_map);
+ }
+
+ if (cell_map->vadj != vadj)
+ {
+ cell_map->vadj = vadj;
+ g_object_ref (cell_map->vadj);
+ gtk_object_sink (GTK_OBJECT (cell_map->vadj));
+
+ g_signal_connect (cell_map->vadj, "changed",
+ G_CALLBACK (update_adjustment), cell_map);
+ g_signal_connect (cell_map->vadj, "value_changed",
+ G_CALLBACK (update_adjustment), cell_map);
+
+ update_adjustment (vadj, cell_map);
+ }
+}
+
+static void
+update_adjustment (GtkAdjustment *adj,
+ OcfsCellMap *cell_map)
+{
+ gfloat prev_val;
+
+ prev_val = adj->value;
+
+ adj->value = MIN (adj->value, adj->upper - adj->page_size);
+ adj->value = MAX (adj->value, 0.0);
+
+ if (adj->value != prev_val)
+ {
+ g_signal_handlers_block_by_func (adj, update_adjustment, cell_map);
+ gtk_adjustment_changed (adj);
+ g_signal_handlers_unblock_by_func (adj, update_adjustment, cell_map);
+ }
+
+ if (GTK_WIDGET_REALIZED (cell_map))
+ {
+ if (adj == cell_map->vadj)
+ gtk_widget_queue_draw (GTK_WIDGET (cell_map));
+ else
+ g_warning ("Horizontal scrolling not supported");
+ }
+}
+
+static void
+compute_vertical_scroll (OcfsCellMap *cell_map)
+{
+ gint width, height;
+ gint per_row, real_height;
+ gint old_value;
+
+ old_value = (gint) cell_map->vadj->value;
+
+ width = GTK_WIDGET (cell_map)->allocation.width - 1;
+ height = GTK_WIDGET (cell_map)->allocation.height - 1;
+
+ per_row = width / cell_map->cell_width;
+ per_row = MAX (1, per_row);
+
+ real_height = (cell_map->map->len / per_row + 1) * cell_map->cell_height;
+
+ cell_map->vadj->upper = real_height;
+
+ cell_map->vadj->step_increment = MIN (cell_map->vadj->upper, cell_map->cell_height);
+ cell_map->vadj->page_increment = MIN (cell_map->vadj->upper, height - cell_map->cell_height * 2);
+ cell_map->vadj->page_size = MIN (cell_map->vadj->upper, height);
+ cell_map->vadj->value = MIN (cell_map->vadj->value, cell_map->vadj->upper - cell_map->vadj->page_size);
+ cell_map->vadj->value = MAX (cell_map->vadj->value, 0.0);
+
+ g_signal_emit_by_name (cell_map->vadj, "changed");
+}
+
+#ifdef CELLMAP_TEST
+
+#define LENGTH 160
+
+int
+main (int argc,
+ char **argv)
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *scrl_win;
+ GtkWidget *cell_map;
+ GtkWidget *button;
+ OcfsBitmap *map;
+ guchar *data;
+ gint i;
+
+ gtk_init (&argc, &argv);
+
+ data = g_new (guchar, LENGTH);
+
+ for (i = 0; i < LENGTH; i++)
+ data[i] = i % 2 ? 0xff : 0x00;
+
+ map = ocfs_bitmap_new (data, LENGTH);
+
+ window = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
+ "type", GTK_WINDOW_TOPLEVEL,
+ "border_width", 5,
+ NULL),
+ "signal::delete-event", gtk_main_quit, NULL,
+ NULL);
+
+ vbox = gtk_vbox_new (FALSE, 5);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ scrl_win = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
+ "hscrollbar_policy", GTK_POLICY_NEVER,
+ "vscrollbar_policy", GTK_POLICY_ALWAYS,
+ "parent", vbox,
+ NULL);
+
+ cell_map = g_object_new (OCFS_TYPE_CELL_MAP,
+ "map", map,
+ "parent", scrl_win,
+ NULL);
+
+ button = g_object_connect (g_object_new (GTK_TYPE_BUTTON,
+ "label", "Whee!",
+ NULL),
+ "signal::clicked", gtk_main_quit, NULL,
+ NULL);
+ gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (window);
+
+ gtk_main ();
+
+ return 0;
+}
+#endif
Copied: trunk/ocfs2tool/ocfscellmap.h (from rev 256, trunk/ocfstool/ocfscellmap.h)
===================================================================
--- trunk/ocfstool/ocfscellmap.h 2004-09-24 23:55:36 UTC (rev 256)
+++ trunk/ocfs2tool/ocfscellmap.h 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,78 @@
+/*
+ * ocfscellmap.h
+ *
+ * Function prototypes for related 'C' file.
+ *
+ * Copyright (C) 2002 Oracle Corporation. All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Manish Singh
+ */
+
+#ifndef __OCFS_CELL_MAP_H__
+#define __OCFS_CELL_MAP_H__
+
+
+#include <gtk/gtk.h>
+
+#include "ocfsbitmap.h"
+
+
+#define OCFS_TYPE_CELL_MAP (ocfs_cell_map_get_type ())
+#define OCFS_CELL_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OCFS_TYPE_CELL_MAP, OcfsCellMap))
+#define OCFS_CELL_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OCFS_TYPE_CELL_MAP, OcfsCellMapClass))
+#define OCFS_IS_CELL_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OCFS_TYPE_CELL_MAP))
+#define OCFS_IS_CELL_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OCFS_TYPE_CELL_MAP))
+#define OCFS_CELL_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OCFS_TYPE_CELL_MAP, OcfsCellMapCLass))
+
+
+typedef struct _OcfsCellMap OcfsCellMap;
+typedef struct _OcfsCellMapClass OcfsCellMapClass;
+
+struct _OcfsCellMap
+{
+ GtkDrawingArea parent_instance;
+
+ OcfsBitmap *map;
+
+ gint cell_width;
+ gint cell_height;
+
+ GtkAdjustment *hadj;
+ GtkAdjustment *vadj;
+};
+
+struct _OcfsCellMapClass
+{
+ GtkDrawingAreaClass parent_class;
+
+ void (*set_scroll_adjustments) (OcfsCellMap *bd,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+};
+
+
+GType ocfs_cell_map_get_type (void);
+GtkWidget *ocfs_cell_map_new (OcfsBitmap *map);
+void ocfs_cell_map_set_map (OcfsCellMap *cell_map,
+ OcfsBitmap *map);
+void ocfs_cell_map_set_cell_props (OcfsCellMap *cell_map,
+ gint cell_width,
+ gint cell_height);
+
+
+#endif /* __OCFS_CELL_MAP_H__ */
Added: trunk/ocfs2tool/ocfsmarshal.list
===================================================================
--- trunk/ocfs2tool/ocfsmarshal.list 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/ocfsmarshal.list 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1 @@
+VOID: OBJECT, OBJECT
Copied: trunk/ocfs2tool/ocfsplist.c (from rev 256, trunk/ocfstool/ocfsplist.c)
===================================================================
--- trunk/ocfstool/ocfsplist.c 2004-09-24 23:55:36 UTC (rev 256)
+++ trunk/ocfs2tool/ocfsplist.c 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,331 @@
+/*
+ * ocfsplist.c
+ *
+ * Create a list of valid partitions
+ *
+ * Copyright (C) 2002 Oracle Corporation. All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Manish Singh
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <glib.h>
+
+#include "ocfs2.h"
+
+#include "ocfsplist.h"
+
+
+typedef struct _BuildData BuildData;
+
+struct _BuildData
+{
+ gboolean unmounted;
+ GList *list;
+};
+
+
+static gboolean check_partition_type (const gchar *device,
+ OcfsFSType *type);
+static gboolean valid_device (const gchar *device,
+ gboolean no_ocfs_check,
+ OcfsFSType *type);
+static void partition_info_fill (GHashTable *info);
+static gboolean list_builder (gpointer key,
+ gpointer value,
+ gpointer user_data);
+
+
+static gboolean
+check_partition_type (const gchar *device,
+ OcfsFSType *type)
+{
+ errcode_t ret;
+ ocfs2_filesys *fs;
+
+ ret = ocfs2_open (device, OCFS2_FLAG_RO, 0, 0, &fs);
+
+ if (ret)
+ {
+ if (ret == OCFS2_ET_OCFS_REV)
+ *type = OCFS_FS_TYPE_OCFS;
+ else
+ return FALSE;
+ }
+ else
+ *type = OCFS_FS_TYPE_OCFS2;
+
+ ocfs2_close (fs);
+ return TRUE;
+}
+
+static gboolean
+valid_device (const gchar *device,
+ gboolean no_ocfs_check,
+ OcfsFSType *type)
+{
+ gboolean is_bad = FALSE;
+ struct stat sbuf;
+ FILE *f;
+ gchar buf[100], *proc, *d;
+ gint i, fd;
+
+ if ((stat (device, &sbuf) != 0) ||
+ (!S_ISBLK (sbuf.st_mode)) ||
+ ((sbuf.st_mode & 0222) == 0))
+ return FALSE;
+
+ if (strncmp ("/dev/hd", device, 7) == 0)
+ {
+ i = strlen (device) - 1;
+ while (i > 5 && isdigit (device[i]))
+ i--;
+
+ d = g_strndup (device + 5, i + 1);
+ proc = g_strconcat ("/proc/ide/", d, "/media", NULL);
+ g_free (d);
+
+ f = fopen (proc, "r");
+ g_free (proc);
+
+ if (f != NULL && fgets (buf, sizeof (buf), f))
+ is_bad = ((strncmp (buf, "cdrom", 5) == 0) ||
+ (strncmp (buf, "tape", 4) == 0));
+
+ if (f)
+ fclose (f);
+
+ if (is_bad)
+ return FALSE;
+ }
+
+#ifndef DEVEL_MACHINE
+ fd = open (device, O_RDWR);
+ if (fd == -1)
+ return FALSE;
+ close (fd);
+
+ return no_ocfs_check ? TRUE : check_partition_type (device, type);
+#else
+ fd = 0;
+ *type = OCFS_FS_TYPE_OCFS2;
+ return TRUE;
+#endif
+}
+
+static void
+partition_info_fill (GHashTable *info)
+{
+ FILE *proc;
+ gchar line[100], name[100], *device;
+ GSList *list;
+ gint i;
+ gchar *p;
+
+ proc = fopen ("/proc/partitions", "r");
+ if (proc == NULL)
+ return;
+
+ while (fgets (line, sizeof(line), proc) != NULL)
+ {
+ if (sscanf(line, "%*d %*d %*d %99[^ \t\n]", name) != 1)
+ continue;
+
+ device = g_strconcat ("/dev/", name, NULL);
+
+ i = strlen (device) - 1;
+ if (isdigit (device[i]))
+ {
+ while (i > 0 && isdigit (device[i]))
+ i--;
+
+ p = g_strndup (device, i + 1);
+ list = g_hash_table_lookup (info, p);
+
+ if (list == NULL)
+ {
+ list = g_slist_prepend (NULL, device);
+ g_hash_table_insert (info, p, list);
+ }
+ else
+ {
+ if (strcmp (p, list->data) == 0)
+ {
+ g_free (list->data);
+ list->data = device;
+ }
+ else
+ g_slist_append (list, device);
+
+ g_free (p);
+ }
+ }
+ else if (!g_hash_table_lookup (info, device))
+ {
+ list = g_slist_prepend (NULL, g_strdup (device));
+ g_hash_table_insert (info, device, list);
+ }
+ else
+ g_free (device);
+ }
+
+ fclose (proc);
+}
+
+static gboolean
+list_builder (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ BuildData *bdata;
+ GSList *list, *last;
+ gchar *device;
+ gchar mountpoint[PATH_MAX];
+ OcfsPartitionInfo *info;
+ gint flags;
+ OcfsFSType type;
+ errcode_t ret;
+
+ bdata = user_data;
+ list = value;
+
+ while (list)
+ {
+ device = list->data;
+
+ if (valid_device (device, bdata->unmounted, &type))
+ {
+ info = g_new (OcfsPartitionInfo, 1);
+
+ info->device = g_strdup (device);
+ info->type = type;
+
+ ret = ocfs2_check_mount_point (device, &flags, mountpoint, PATH_MAX);
+
+ if (ret == 0)
+ {
+ if (flags & OCFS2_MF_MOUNTED)
+ info->mountpoint = g_strdup (mountpoint);
+ else
+ info->mountpoint = NULL;
+ }
+ else
+ info->mountpoint = NULL;
+
+ if (bdata->unmounted)
+ {
+ if (info->mountpoint)
+ {
+ g_free (info->mountpoint);
+ g_free (info->device);
+ }
+ else
+ bdata->list = g_list_prepend (bdata->list, info->device);
+
+ g_free (info);
+ }
+ else
+ bdata->list = g_list_prepend (bdata->list, info);
+ }
+
+ last = list;
+ list = list->next;
+
+ g_free (device);
+ g_slist_free_1 (last);
+ }
+
+ g_free (key);
+
+ return TRUE;
+}
+
+#ifdef LIST_TEST_HASH
+static void
+print_hash (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GSList *list;
+
+ g_print ("Key: %s; Values:", (gchar *) key);
+ for (list = value; list != NULL; list = list->next)
+ g_print (" %s", (gchar *) list->data);
+ g_print ("\n");
+}
+#endif
+
+GList *
+ocfs_partition_list (gboolean unmounted)
+{
+ GHashTable *info;
+ BuildData bdata = { unmounted, NULL };
+
+ info = g_hash_table_new (g_str_hash, g_str_equal);
+
+ partition_info_fill (info);
+
+#ifdef LIST_TEST_HASH
+ g_hash_table_foreach (info, print_hash, NULL);
+#endif
+
+ g_hash_table_foreach_remove (info, list_builder, &bdata);
+
+ g_hash_table_destroy (info);
+
+ return bdata.list;
+}
+
+#ifdef LIST_TEST
+int
+main (int argc,
+ char **argv)
+{
+ GList *plist, *list;
+ OcfsPartitionInfo *info;
+
+ g_print ("All:\n");
+
+ plist = ocfs_partition_list (FALSE);
+
+ for (list = plist; list; list = list->next)
+ {
+ info = list->data;
+ g_print ("Device: %s; Mountpoint %s; Type %s\n",
+ info->device, info->mountpoint,
+ info->type == OCFS_FS_TYPE_OCFS2 ? "ocfs2" : "ocfs");
+ }
+
+ g_print ("Unmounted:\n");
+
+ plist = ocfs_partition_list (TRUE);
+
+ for (list = plist; list; list = list->next)
+ g_print ("Device: %s\n", (gchar *) list->data);
+
+ return 0;
+}
+#endif
Copied: trunk/ocfs2tool/ocfsplist.h (from rev 256, trunk/ocfstool/ocfsplist.h)
===================================================================
--- trunk/ocfstool/ocfsplist.h 2004-09-24 23:55:36 UTC (rev 256)
+++ trunk/ocfs2tool/ocfsplist.h 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,51 @@
+/*
+ * ocfsplist.h
+ *
+ * Function prototypes for related 'C' file.
+ *
+ * Copyright (C) 2002 Oracle Corporation. All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Author: Manish Singh
+ */
+
+#ifndef __OCFS_PARTITION_LIST_H__
+#define __OCFS_PARTITION_LIST_H__
+
+#include <glib.h>
+
+
+typedef enum
+{
+ OCFS_FS_TYPE_OCFS,
+ OCFS_FS_TYPE_OCFS2
+} OcfsFSType;
+
+typedef struct _OcfsPartitionInfo OcfsPartitionInfo;
+
+struct _OcfsPartitionInfo
+{
+ gchar *device;
+ gchar *mountpoint;
+ OcfsFSType type;
+};
+
+
+GList *ocfs_partition_list (gboolean unmounted);
+
+
+#endif /* __OCFS_PARTITION_LIST_H__ */
Added: trunk/ocfs2tool/process.py
===================================================================
--- trunk/ocfs2tool/process.py 2004-09-27 02:57:27 UTC (rev 260)
+++ trunk/ocfs2tool/process.py 2004-09-27 05:59:59 UTC (rev 261)
@@ -0,0 +1,152 @@
+import os
+import types
+import fcntl
+import popen2
+
+import gobject
+import gtk
+
+from guiutil import set_props
+
+INTERVAL = 100
+TIMEOUT = 10000
+
+class Process:
+ def __init__(self, command, title, desc, parent=None, spin_now=True):
+ if isinstance(command, types.StringTypes):
+ if len(command.split(None, 1)) < 2:
+ command = (command,)
+
+ self.command = command
+
+ self.title = title
+ self.desc = desc
+
+ self.parent = parent
+
+ self.spin_now = spin_now
+
+ self.pipe = popen2.Popen4(self.command)
+
+ def reap(self):
+ self.success = False
+ self.killed = False
+
+ self.count = TIMEOUT // INTERVAL
+ self.threshold = self.count - INTERVAL * 10
+
+ self.dialog = None
+
+ if self.spin_now:
+ self.count = TIMEOUT * 60
+ self.make_progress_box()
+
+ timeout_id = gobject.timeout_add(INTERVAL, self.timeout)
+
+ fromchild = self.pipe.fromchild
+
+ fileno = fromchild.fileno()
+ flags = fcntl.fcntl(fileno, fcntl.F_GETFL, 0)
+ flags = flags | os.O_NONBLOCK
+ fcntl.fcntl(fileno, fcntl.F_SETFL, flags)
+
+ self.output = ''
+ output_id = gobject.io_add_watch(fromchild, gobject.IO_IN, self.read)
+
+ gtk.main()
+
+ if self.dialog:
+ self.dialog.destroy()
+
+ gobject.source_remove(output_id)
+ gobject.source_remove(timeout_id)
+
+ if not self.success:
+ if self.killed:
+ if self.output:
+ self.output += '\n'
+
+ self.output += 'Killed prematurely.'
+
+ return self.success, self.output, self.killed
+
+ def timeout(self):
+ self.count = self.count - 1
+
+ ret = self.pipe.poll()
+
+ if ret != -1:
+ self.success = not os.WEXITSTATUS(ret)
+ gtk.main_quit()
+ return True
+
+ if self.count < 1:
+ self.kill()
+ return True
+
+ if self.count < self.threshold and not self.dialog:
+ self.make_progess_box()
+
+ if self.dialog:
+ self.pbar.pulse()
+
+ return True
+
+ def kill(self):
+ self.success = False
+ self.killed = True
+
+ os.kill(self.pipe.pid, 15)
+ gobject.timeout_add(INTERVAL * 5, self.kill_timeout)
+
+ gtk.main_quit()
+
+ def kill_timeout(self):
+ if self.pipe.poll() == -1:
+ os.kill(self.pipe.pid, 9)
+ self.kill_9 = True
+
+ return False
+
+ def make_progress_box(self):
+ self.dialog = gtk.Window()
+ set_props(self.dialog, title=self.title,
+ resizable=False,
+ modal=True,
+ type_hint=gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+
+ def ignore(w, e):
+ return True
+ self.dialog.connect('delete-event', ignore)
+
+ self.dialog.set_transient_for(self.parent)
+
+ vbox = gtk.VBox()
+ set_props(vbox, spacing=0,
+ homogeneous=False,
+ border_width=4,
+ parent=self.dialog)
+
+ label = gtk.Label(self.desc + '...')
+ vbox.pack_start(label, expand=False, fill=False)
+
+ self.pbar = gtk.ProgressBar()
+ vbox.pack_start(self.pbar, expand=False, fill=False)
+
+ self.dialog.show_all()
+
+ def read(self, fd, cond):
+ if cond & gtk.gdk.INPUT_READ:
+ try:
+ self.output += fd.read(1024)
+ except IOError, e:
+ return False
+
+ return True
+
+def main():
+ process = Process('echo Hello; sleep 10', 'Sleep', 'Sleeping')
+ print process.reap()
+
+if __name__ == '__main__':
+ main()
More information about the Ocfs2-tools-commits
mailing list