mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 05:31:15 +00:00
New import (the old repo got busted, just had 4 revs anyways)
This commit is contained in:
parent
07391578c9
commit
71cddb7d78
20 changed files with 4410 additions and 0 deletions
53
debug-viewer/GstDebugViewer/Common/Data.py
Normal file
53
debug-viewer/GstDebugViewer/Common/Data.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Development Utilities
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer development utilities common Data module"""
|
||||||
|
|
||||||
|
import pygtk
|
||||||
|
pygtk.require ("2.0")
|
||||||
|
|
||||||
|
import gobject
|
||||||
|
|
||||||
|
class Dispatcher (object):
|
||||||
|
|
||||||
|
def __call__ (self, iterator):
|
||||||
|
|
||||||
|
raise NotImplementedError ("derived classes must override this method")
|
||||||
|
|
||||||
|
class DefaultDispatcher (Dispatcher):
|
||||||
|
|
||||||
|
def __call__ (self, iterator):
|
||||||
|
|
||||||
|
for x in iterator:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class GSourceDispatcher (Dispatcher):
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
Dispatcher.__init__ (self)
|
||||||
|
|
||||||
|
self.source_id = None
|
||||||
|
|
||||||
|
def __call__ (self, iterator):
|
||||||
|
|
||||||
|
if self.source_id is not None:
|
||||||
|
gobject.source_remove (self.source_id)
|
||||||
|
|
||||||
|
self.source_id = gobject.idle_add (iterator.next)
|
467
debug-viewer/GstDebugViewer/Common/GUI.py
Normal file
467
debug-viewer/GstDebugViewer/Common/GUI.py
Normal file
|
@ -0,0 +1,467 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Development Utilities
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer development utilities common GUI module"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pygtk
|
||||||
|
pygtk.require ("2.0")
|
||||||
|
del pygtk
|
||||||
|
|
||||||
|
import gobject
|
||||||
|
import gtk
|
||||||
|
|
||||||
|
from GstDebugViewer.Common import utils
|
||||||
|
|
||||||
|
class Actions (dict):
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
dict.__init__ (self)
|
||||||
|
|
||||||
|
self.groups = ()
|
||||||
|
|
||||||
|
def __getattr__ (self, name):
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self[name]
|
||||||
|
except KeyError:
|
||||||
|
if "_" in name:
|
||||||
|
try:
|
||||||
|
return self[name.replace ("_", "-")]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
raise AttributeError ("no action with name %r" % (name,))
|
||||||
|
|
||||||
|
def add_group (self, group):
|
||||||
|
|
||||||
|
self.groups += (group,)
|
||||||
|
for action in group.list_actions ():
|
||||||
|
self[action.props.name] = action
|
||||||
|
|
||||||
|
class Widgets (dict):
|
||||||
|
|
||||||
|
def __init__ (self, glade_tree):
|
||||||
|
|
||||||
|
widgets = glade_tree.get_widget_prefix ("")
|
||||||
|
dict.__init__ (self, ((w.name, w,) for w in widgets))
|
||||||
|
|
||||||
|
def __getattr__ (self, name):
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self[name]
|
||||||
|
except KeyError:
|
||||||
|
if "_" in name:
|
||||||
|
try:
|
||||||
|
return self[name.replace ("_", "-")]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
raise AttributeError ("no widget with name %r" % (name,))
|
||||||
|
|
||||||
|
class WidgetFactory (object):
|
||||||
|
|
||||||
|
def __init__ (self, glade_filename):
|
||||||
|
|
||||||
|
self.filename = glade_filename
|
||||||
|
|
||||||
|
def make (self, widget_name, autoconnect = None):
|
||||||
|
|
||||||
|
glade_tree = gtk.glade.XML (self.filename, widget_name)
|
||||||
|
|
||||||
|
if autoconnect is not None:
|
||||||
|
glade_tree.signal_autoconnect (autoconnect)
|
||||||
|
|
||||||
|
return Widgets (glade_tree)
|
||||||
|
|
||||||
|
def make_one (self, widget_name):
|
||||||
|
|
||||||
|
glade_tree = gtk.glade.XML (self.filename, widget_name)
|
||||||
|
|
||||||
|
return glade_tree.get_widget (widget_name)
|
||||||
|
|
||||||
|
class UIFactory (object):
|
||||||
|
|
||||||
|
def __init__ (self, ui_filename, actions = None):
|
||||||
|
|
||||||
|
self.filename = ui_filename
|
||||||
|
if actions:
|
||||||
|
self.action_groups = actions.groups
|
||||||
|
else:
|
||||||
|
self.action_groups = ()
|
||||||
|
|
||||||
|
def make (self, extra_actions = None):
|
||||||
|
|
||||||
|
ui_manager = gtk.UIManager ()
|
||||||
|
for action_group in self.action_groups:
|
||||||
|
ui_manager.insert_action_group (action_group, 0)
|
||||||
|
if extra_actions:
|
||||||
|
for action_group in extra_actions.groups:
|
||||||
|
ui_manager.insert_action_group (action_group, 0)
|
||||||
|
ui_manager.add_ui_from_file (self.filename)
|
||||||
|
ui_manager.ensure_update ()
|
||||||
|
|
||||||
|
return ui_manager
|
||||||
|
|
||||||
|
class MetaModel (gobject.GObjectMeta):
|
||||||
|
|
||||||
|
"""Meta class for easy setup of gtk tree models.
|
||||||
|
|
||||||
|
Looks for a class attribute named `columns' which must be set to a
|
||||||
|
sequence of the form name1, type1, name2, type2, ..., where the
|
||||||
|
names are strings. This metaclass adds the following attributes
|
||||||
|
to created classes:
|
||||||
|
|
||||||
|
cls.column_types = (type1, type2, ...)
|
||||||
|
cls.column_ids = (0, 1, ...)
|
||||||
|
cls.name1 = 0
|
||||||
|
cls.name2 = 1
|
||||||
|
...
|
||||||
|
|
||||||
|
Example: A gtk.ListStore derived model can use
|
||||||
|
|
||||||
|
columns = ("COL_NAME", str, "COL_VALUE", str)
|
||||||
|
|
||||||
|
and use this in __init__:
|
||||||
|
|
||||||
|
gtk.ListStore.__init__ (self, *self.column_types)
|
||||||
|
|
||||||
|
Then insert data like this:
|
||||||
|
|
||||||
|
self.set (self.append (),
|
||||||
|
self.COL_NAME, "spam",
|
||||||
|
self.COL_VALUE, "ham")
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__ (cls, name, bases, dict):
|
||||||
|
|
||||||
|
super (MetaModel, cls).__init__ (name, bases, dict)
|
||||||
|
|
||||||
|
spec = tuple (cls.columns)
|
||||||
|
|
||||||
|
column_names = spec[::2]
|
||||||
|
column_types = spec[1::2]
|
||||||
|
column_indices = range (len (column_names))
|
||||||
|
|
||||||
|
for col_index, col_name, in zip (column_indices, column_names):
|
||||||
|
setattr (cls, col_name, col_index)
|
||||||
|
|
||||||
|
cls.column_types = column_types
|
||||||
|
cls.column_ids = tuple (column_indices)
|
||||||
|
|
||||||
|
class Manager (object):
|
||||||
|
|
||||||
|
"""GUI Manager base class."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def iter_item_classes (cls):
|
||||||
|
|
||||||
|
msg = "%s class does not support manager item class access"
|
||||||
|
raise NotImplementedError (msg % (cls.__name__,))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_item_class (self, **kw):
|
||||||
|
|
||||||
|
return self.__find_by_attrs (self.iter_item_classes (), kw)
|
||||||
|
|
||||||
|
def iter_items (self):
|
||||||
|
|
||||||
|
msg = "%s object does not support manager item access"
|
||||||
|
raise NotImplementedError (msg % (type (self).__name__,))
|
||||||
|
|
||||||
|
def find_item (self, **kw):
|
||||||
|
|
||||||
|
return self.__find_by_attrs (self.iter_items (), kw)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __find_by_attrs (i, kw):
|
||||||
|
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
|
if len (kw) != 1:
|
||||||
|
raise ValueError ("need exactly one keyword argument")
|
||||||
|
|
||||||
|
attr, value = kw.items ()[0]
|
||||||
|
getter = attrgetter (attr)
|
||||||
|
|
||||||
|
for item in i:
|
||||||
|
if getter (item) == value:
|
||||||
|
return item
|
||||||
|
else:
|
||||||
|
raise KeyError ("no item such that item.%s == %r" % (attr, value,))
|
||||||
|
|
||||||
|
class StateString (object):
|
||||||
|
|
||||||
|
"""Descriptor for binding to AppState classes."""
|
||||||
|
|
||||||
|
def __init__ (self, option, section = None):
|
||||||
|
|
||||||
|
self.option = option
|
||||||
|
self.section = section
|
||||||
|
|
||||||
|
def get_section (self, state):
|
||||||
|
|
||||||
|
if self.section is None:
|
||||||
|
return state._default_section
|
||||||
|
else:
|
||||||
|
return self.section
|
||||||
|
|
||||||
|
def get_getter (self, state):
|
||||||
|
|
||||||
|
return state._parser.get
|
||||||
|
|
||||||
|
def get_default (self, state):
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __get__ (self, state, state_class = None):
|
||||||
|
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
if state is None:
|
||||||
|
return self
|
||||||
|
|
||||||
|
getter = self.get_getter (state)
|
||||||
|
section = self.get_section (state)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return getter (section, self.option)
|
||||||
|
except (ConfigParser.NoSectionError,
|
||||||
|
ConfigParser.NoOptionError,):
|
||||||
|
return self.get_default (state)
|
||||||
|
|
||||||
|
def __set__ (self, state, value):
|
||||||
|
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
value = ""
|
||||||
|
|
||||||
|
section = self.get_section (state)
|
||||||
|
option = self.option
|
||||||
|
option_value = str (value)
|
||||||
|
|
||||||
|
try:
|
||||||
|
state._parser.set (section, option, option_value)
|
||||||
|
except ConfigParser.NoSectionError:
|
||||||
|
state._parser.add_section (section)
|
||||||
|
state._parser.set (section, option, option_value)
|
||||||
|
|
||||||
|
class StateBool (StateString):
|
||||||
|
|
||||||
|
"""Descriptor for binding to AppState classes."""
|
||||||
|
|
||||||
|
def get_getter (self, state):
|
||||||
|
|
||||||
|
return state._parser.getboolean
|
||||||
|
|
||||||
|
class StateInt (StateString):
|
||||||
|
|
||||||
|
"""Descriptor for binding to AppState classes."""
|
||||||
|
|
||||||
|
def get_getter (self, state):
|
||||||
|
|
||||||
|
return state._parser.getint
|
||||||
|
|
||||||
|
class StateInt4 (StateString):
|
||||||
|
|
||||||
|
"""Descriptor for binding to AppState classes. This implements storing a
|
||||||
|
tuple of 4 integers."""
|
||||||
|
|
||||||
|
def __get__ (self, state, state_class = None):
|
||||||
|
|
||||||
|
if state is None:
|
||||||
|
return self
|
||||||
|
|
||||||
|
value = StateString.__get__ (self, state)
|
||||||
|
|
||||||
|
try:
|
||||||
|
l = value.split (",")
|
||||||
|
if len (l) != 4:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return tuple ((int (v) for v in l))
|
||||||
|
except (AttributeError, TypeError, ValueError,):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __set__ (self, state, value):
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
svalue = ""
|
||||||
|
elif len (value) != 4:
|
||||||
|
raise ValueError ("value needs to be a 4-sequence, or None")
|
||||||
|
else:
|
||||||
|
svalue = ", ".join ((str (v) for v in value))
|
||||||
|
|
||||||
|
return StateString.__set__ (self, state, svalue)
|
||||||
|
|
||||||
|
class StateItem (StateString):
|
||||||
|
|
||||||
|
"""Descriptor for binding to AppState classes. This implements storing a
|
||||||
|
class controlled by a Manager class."""
|
||||||
|
|
||||||
|
def __init__ (self, option, manager_class, section = None):
|
||||||
|
|
||||||
|
StateString.__init__ (self, option, section = section)
|
||||||
|
|
||||||
|
self.manager = manager_class
|
||||||
|
|
||||||
|
def __get__ (self, state, state_class = None):
|
||||||
|
|
||||||
|
if state is None:
|
||||||
|
return self
|
||||||
|
|
||||||
|
value = StateString.__get__ (self, state)
|
||||||
|
|
||||||
|
if not value:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.parse_item (value)
|
||||||
|
|
||||||
|
def __set__ (self, state, value):
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
svalue = ""
|
||||||
|
else:
|
||||||
|
svalue = value.name
|
||||||
|
|
||||||
|
StateString.__set__ (self, state, svalue)
|
||||||
|
|
||||||
|
def parse_item (self, value):
|
||||||
|
|
||||||
|
name = value.strip ()
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self.manager.find_item_class (name = name)
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
class StateItemList (StateItem):
|
||||||
|
|
||||||
|
"""Descriptor for binding to AppState classes. This implements storing an
|
||||||
|
ordered set of Manager items."""
|
||||||
|
|
||||||
|
def __get__ (self, state, state_class = None):
|
||||||
|
|
||||||
|
if state is None:
|
||||||
|
return self
|
||||||
|
|
||||||
|
value = StateString.__get__ (self, state)
|
||||||
|
|
||||||
|
if not value:
|
||||||
|
return []
|
||||||
|
|
||||||
|
classes = []
|
||||||
|
for name in value.split (","):
|
||||||
|
item_class = self.parse_item (name)
|
||||||
|
if item_class is None:
|
||||||
|
continue
|
||||||
|
if not item_class in classes:
|
||||||
|
classes.append (item_class)
|
||||||
|
|
||||||
|
return classes
|
||||||
|
|
||||||
|
def __set__ (self, state, value):
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
svalue = ""
|
||||||
|
else:
|
||||||
|
svalue = ", ".join ((v.name for v in value))
|
||||||
|
|
||||||
|
StateString.__set__ (self, state, svalue)
|
||||||
|
|
||||||
|
class AppState (object):
|
||||||
|
|
||||||
|
_default_section = "state"
|
||||||
|
|
||||||
|
def __init__ (self, filename, old_filenames = ()):
|
||||||
|
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
self._filename = filename
|
||||||
|
self._parser = ConfigParser.RawConfigParser ()
|
||||||
|
success = self._parser.read ([filename])
|
||||||
|
if not success:
|
||||||
|
for old_filename in old_filenames:
|
||||||
|
success = self._parser.read ([old_filename])
|
||||||
|
if success:
|
||||||
|
break
|
||||||
|
|
||||||
|
def save (self):
|
||||||
|
|
||||||
|
# TODO Py2.5: Use 'with' statement.
|
||||||
|
fp = utils.SaveWriteFile (self._filename, "wt")
|
||||||
|
try:
|
||||||
|
self._parser.write (fp)
|
||||||
|
except:
|
||||||
|
fp.discard ()
|
||||||
|
else:
|
||||||
|
fp.close ()
|
||||||
|
|
||||||
|
class WindowState (object):
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
self.logger = logging.getLogger ("ui.window-state")
|
||||||
|
|
||||||
|
self.is_maximized = False
|
||||||
|
|
||||||
|
def attach (self, window, state):
|
||||||
|
|
||||||
|
self.window = window
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
self.window.connect ("window-state-event",
|
||||||
|
self.handle_window_state_event)
|
||||||
|
|
||||||
|
geometry = self.state.geometry
|
||||||
|
if geometry:
|
||||||
|
self.window.move (*geometry[:2])
|
||||||
|
self.window.set_default_size (*geometry[2:])
|
||||||
|
|
||||||
|
if self.state.maximized:
|
||||||
|
self.logger.debug ("initially maximized")
|
||||||
|
self.window.maximize ()
|
||||||
|
|
||||||
|
def detach (self):
|
||||||
|
|
||||||
|
window = self.window
|
||||||
|
|
||||||
|
self.state.maximized = self.is_maximized
|
||||||
|
if not self.is_maximized:
|
||||||
|
position = tuple (window.get_position ())
|
||||||
|
size = tuple (window.get_size ())
|
||||||
|
self.state.geometry = position + size
|
||||||
|
|
||||||
|
self.window.disconnect_by_func (self.handle_window_state_event)
|
||||||
|
self.window = None
|
||||||
|
|
||||||
|
def handle_window_state_event (self, window, event):
|
||||||
|
|
||||||
|
if not event.changed_mask & gtk.gdk.WINDOW_STATE_MAXIMIZED:
|
||||||
|
return
|
||||||
|
|
||||||
|
if event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED:
|
||||||
|
self.logger.debug ("maximized")
|
||||||
|
self.is_maximized = True
|
||||||
|
else:
|
||||||
|
self.logger.debug ("unmaximized")
|
||||||
|
self.is_maximized = False
|
479
debug-viewer/GstDebugViewer/Common/Main.py
Normal file
479
debug-viewer/GstDebugViewer/Common/Main.py
Normal file
|
@ -0,0 +1,479 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Development Utilities
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer development utilities common main module."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import traceback
|
||||||
|
from operator import attrgetter
|
||||||
|
import logging
|
||||||
|
import locale
|
||||||
|
import gettext
|
||||||
|
from gettext import gettext as _, ngettext
|
||||||
|
|
||||||
|
import pygtk
|
||||||
|
pygtk.require ("2.0")
|
||||||
|
del pygtk
|
||||||
|
|
||||||
|
import gobject
|
||||||
|
|
||||||
|
class ExceptionHandler (object):
|
||||||
|
|
||||||
|
exc_types = (Exception,)
|
||||||
|
priority = 50
|
||||||
|
inherit_fork = True
|
||||||
|
|
||||||
|
_handling_exception = False
|
||||||
|
|
||||||
|
def __call__ (self, exc_type, exc_value, exc_traceback):
|
||||||
|
|
||||||
|
raise NotImplementedError ("derived classes need to override this method")
|
||||||
|
|
||||||
|
class DefaultExceptionHandler (ExceptionHandler):
|
||||||
|
|
||||||
|
# TODO Py2.5: In Python 2.5, this succeeds. Remove the try...except block
|
||||||
|
# once we depend on 2.5.
|
||||||
|
try:
|
||||||
|
exc_types = (BaseException,)
|
||||||
|
except NameError:
|
||||||
|
# Python < 2.5.
|
||||||
|
exc_types = (Exception,)
|
||||||
|
priority = 0
|
||||||
|
inherit_fork = True
|
||||||
|
|
||||||
|
def __init__ (self, excepthook):
|
||||||
|
|
||||||
|
ExceptionHandler.__init__ (self)
|
||||||
|
|
||||||
|
self.excepthook = excepthook
|
||||||
|
|
||||||
|
def __call__ (self, *exc_info):
|
||||||
|
|
||||||
|
return self.excepthook (*exc_info)
|
||||||
|
|
||||||
|
class ExitOnInterruptExceptionHandler (ExceptionHandler):
|
||||||
|
|
||||||
|
exc_types = (KeyboardInterrupt,)
|
||||||
|
priority = 100
|
||||||
|
inherit_fork = False
|
||||||
|
|
||||||
|
exit_status = 2
|
||||||
|
|
||||||
|
def __call__ (self, *args):
|
||||||
|
|
||||||
|
print >> sys.stderr, "Interrupt caught, exiting."
|
||||||
|
|
||||||
|
sys.exit (self.exit_status)
|
||||||
|
|
||||||
|
class MainLoopWrapper (ExceptionHandler):
|
||||||
|
|
||||||
|
priority = 95
|
||||||
|
inherit_fork = False
|
||||||
|
|
||||||
|
def __init__ (self, enter, exit):
|
||||||
|
|
||||||
|
ExceptionHandler.__init__ (self)
|
||||||
|
|
||||||
|
self.exc_info = (None,) * 3
|
||||||
|
self.enter = enter
|
||||||
|
self.exit = exit
|
||||||
|
|
||||||
|
def __call__ (self, *exc_info):
|
||||||
|
|
||||||
|
self.exc_info = exc_info
|
||||||
|
self.exit ()
|
||||||
|
|
||||||
|
def run (self):
|
||||||
|
|
||||||
|
ExceptHookManager.register_handler (self)
|
||||||
|
try:
|
||||||
|
self.enter ()
|
||||||
|
finally:
|
||||||
|
ExceptHookManager.unregister_handler (self)
|
||||||
|
|
||||||
|
if self.exc_info != (None,) * 3:
|
||||||
|
# Re-raise unhandled exception that occured while running the loop.
|
||||||
|
exc_type, exc_value, exc_tb = self.exc_info
|
||||||
|
raise exc_type, exc_value, exc_tb
|
||||||
|
|
||||||
|
class ExceptHookManagerClass (object):
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
self._in_forked_child = False
|
||||||
|
|
||||||
|
self.handlers = []
|
||||||
|
|
||||||
|
def setup (self):
|
||||||
|
|
||||||
|
if sys.excepthook == self.__excepthook:
|
||||||
|
raise ValueError ("already set up")
|
||||||
|
|
||||||
|
hook = sys.excepthook
|
||||||
|
self.__instrument_excepthook ()
|
||||||
|
self.__instrument_fork ()
|
||||||
|
self.register_handler (DefaultExceptionHandler (hook))
|
||||||
|
|
||||||
|
def shutdown (self):
|
||||||
|
|
||||||
|
if sys.excepthook != self.__excepthook:
|
||||||
|
raise ValueError ("not set up")
|
||||||
|
|
||||||
|
self.__restore_excepthook ()
|
||||||
|
self.__restore_fork ()
|
||||||
|
|
||||||
|
def __instrument_excepthook (self):
|
||||||
|
|
||||||
|
hook = sys.excepthook
|
||||||
|
self._original_excepthook = hook
|
||||||
|
sys.excepthook = self.__excepthook
|
||||||
|
|
||||||
|
def __restore_excepthook (self):
|
||||||
|
|
||||||
|
sys.excepthook = self._original_excepthook
|
||||||
|
|
||||||
|
def __instrument_fork (self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
fork = os.fork
|
||||||
|
except AttributeError:
|
||||||
|
# System has no fork() system call.
|
||||||
|
self._original_fork = None
|
||||||
|
else:
|
||||||
|
self._original_fork = fork
|
||||||
|
os.fork = self.__fork
|
||||||
|
|
||||||
|
def __restore_fork (self):
|
||||||
|
|
||||||
|
if not hasattr (os, "fork"):
|
||||||
|
return
|
||||||
|
|
||||||
|
os.fork = self._original_fork
|
||||||
|
|
||||||
|
def entered_forked_child (self):
|
||||||
|
|
||||||
|
self._in_forked_child = True
|
||||||
|
|
||||||
|
for handler in tuple (self.handlers):
|
||||||
|
if not handler.inherit_fork:
|
||||||
|
self.handlers.remove (handler)
|
||||||
|
|
||||||
|
def register_handler (self, handler):
|
||||||
|
|
||||||
|
if self._in_forked_child and not handler.inherit_fork:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.handlers.append (handler)
|
||||||
|
|
||||||
|
def unregister_handler (self, handler):
|
||||||
|
|
||||||
|
self.handlers.remove (handler)
|
||||||
|
|
||||||
|
def __fork (self):
|
||||||
|
|
||||||
|
pid = self._original_fork ()
|
||||||
|
if pid == 0:
|
||||||
|
# Child process.
|
||||||
|
self.entered_forked_child ()
|
||||||
|
return pid
|
||||||
|
|
||||||
|
def __excepthook (self, exc_type, exc_value, exc_traceback):
|
||||||
|
|
||||||
|
for handler in sorted (self.handlers,
|
||||||
|
key = attrgetter ("priority"),
|
||||||
|
reverse = True):
|
||||||
|
|
||||||
|
if handler._handling_exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for type_ in handler.exc_types:
|
||||||
|
if issubclass (exc_type, type_):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
handler._handling_exception = True
|
||||||
|
handler (exc_type, exc_value, exc_traceback)
|
||||||
|
# Not using try...finally on purpose here. If the handler itself
|
||||||
|
# fails with an exception, this prevents recursing into it again.
|
||||||
|
handler._handling_exception = False
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
from warnings import warn
|
||||||
|
warn ("ExceptHookManager: unhandled %r" % (exc_value,),
|
||||||
|
RuntimeWarning,
|
||||||
|
stacklevel = 2)
|
||||||
|
|
||||||
|
ExceptHookManager = ExceptHookManagerClass ()
|
||||||
|
|
||||||
|
class PathsBase (object):
|
||||||
|
|
||||||
|
data_dir = None
|
||||||
|
icon_dir = None
|
||||||
|
locale_dir = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_installed (cls, data_prefix):
|
||||||
|
|
||||||
|
"""Set up paths for running from a regular installation."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_uninstalled (cls, source_dir):
|
||||||
|
|
||||||
|
"""Set up paths for running 'uninstalled' (i.e. directly from the
|
||||||
|
source dist)."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def ensure_setup (cls):
|
||||||
|
|
||||||
|
"""If paths are still not set up, try to set from a fallback."""
|
||||||
|
|
||||||
|
if cls.data_dir is None:
|
||||||
|
source_dir = os.path.dirname (os.path.dirname (os.path.abspath (__file__)))
|
||||||
|
cls.setup_uninstalled (source_dir)
|
||||||
|
|
||||||
|
def __new__ (cls):
|
||||||
|
|
||||||
|
raise RuntimeError ("do not create instances of this class -- "
|
||||||
|
"use the class object directly")
|
||||||
|
|
||||||
|
class PathsProgramBase (PathsBase):
|
||||||
|
|
||||||
|
program_name = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_installed (cls, data_prefix):
|
||||||
|
|
||||||
|
if cls.program_name is None:
|
||||||
|
raise NotImplementedError ("derived classes need to set program_name attribute")
|
||||||
|
|
||||||
|
cls.data_dir = os.path.join (data_prefix, "share", cls.program_name)
|
||||||
|
cls.icon_dir = os.path.join (data_prefix, "share", "icons")
|
||||||
|
cls.locale_dir = os.path.join (data_prefix, "share", "locale")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_uninstalled (cls, source_dir):
|
||||||
|
|
||||||
|
"""Set up paths for running 'uninstalled' (i.e. directly from the
|
||||||
|
source dist)."""
|
||||||
|
|
||||||
|
# This is essential: The GUI module needs to find the .glade file.
|
||||||
|
cls.data_dir = os.path.join (source_dir, "data")
|
||||||
|
|
||||||
|
# The locale data might be missing if "setup.py build" wasn't run.
|
||||||
|
cls.locale_dir = os.path.join (source_dir, "build", "mo")
|
||||||
|
|
||||||
|
# Not setting icon_dir. It is not useful since we don't employ the
|
||||||
|
# needed directory structure in the source dist.
|
||||||
|
|
||||||
|
class OptionError (Exception):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class OptionParser (object):
|
||||||
|
|
||||||
|
def __init__ (self, options):
|
||||||
|
|
||||||
|
self.__entries = []
|
||||||
|
self.__parsers = {}
|
||||||
|
|
||||||
|
self.options = options
|
||||||
|
|
||||||
|
def add_option (self, long_name, short_name = None, description = None,
|
||||||
|
arg_name = None, arg_parser = None, hidden = False):
|
||||||
|
|
||||||
|
flags = 0
|
||||||
|
|
||||||
|
if not short_name:
|
||||||
|
# A deficiency of pygobject:
|
||||||
|
short_name = "\0"
|
||||||
|
|
||||||
|
if not description:
|
||||||
|
description = ""
|
||||||
|
|
||||||
|
if arg_name is None:
|
||||||
|
flags |= gobject.OPTION_FLAG_NO_ARG
|
||||||
|
elif arg_parser is not None:
|
||||||
|
self.__parsers[long_name] = arg_parser
|
||||||
|
|
||||||
|
if hidden:
|
||||||
|
flags |= gobject.OPTION_FLAG_HIDDEN
|
||||||
|
|
||||||
|
self.__entries.append ((long_name, short_name, flags, description,
|
||||||
|
arg_name,))
|
||||||
|
|
||||||
|
def __handle_option (self, option, arg, group):
|
||||||
|
|
||||||
|
for entry in self.__entries:
|
||||||
|
long_name, short_name = entry[:2]
|
||||||
|
arg_name = entry[-1]
|
||||||
|
if (option != "--%s" % (long_name,) and
|
||||||
|
option != "-%s" % (short_name,)):
|
||||||
|
continue
|
||||||
|
attr = long_name.replace ("-", "_")
|
||||||
|
if arg_name is None:
|
||||||
|
value = True
|
||||||
|
elif long_name in self.__parsers:
|
||||||
|
value = self.__parsers[long_name](arg)
|
||||||
|
else:
|
||||||
|
value = arg
|
||||||
|
self.options[attr] = value
|
||||||
|
|
||||||
|
def parse (self, argv):
|
||||||
|
|
||||||
|
context = gobject.OptionContext (self.get_parameter_string ())
|
||||||
|
group = gobject.OptionGroup (None, None, None, self.__handle_option)
|
||||||
|
context.set_main_group (group)
|
||||||
|
group.add_entries (self.__entries)
|
||||||
|
|
||||||
|
try:
|
||||||
|
context.parse (argv)
|
||||||
|
except gobject.GError, exc:
|
||||||
|
raise OptionError (exc.message)
|
||||||
|
|
||||||
|
self.handle_parse_complete ()
|
||||||
|
|
||||||
|
def get_parameter_string (self):
|
||||||
|
|
||||||
|
raise NotImplementedError ("derived classes must override this method")
|
||||||
|
|
||||||
|
def handle_parse_complete (self):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class LogOptionParser (OptionParser):
|
||||||
|
|
||||||
|
"""Like OptionParser, but adds a --log-level option."""
|
||||||
|
|
||||||
|
def __init__ (self, *a, **kw):
|
||||||
|
|
||||||
|
OptionParser.__init__ (self, *a, **kw)
|
||||||
|
|
||||||
|
# TODO: Re-evaluate usage of log levels to use less of them. Like
|
||||||
|
# unifying warning, error and critical.
|
||||||
|
|
||||||
|
self.add_option ("log-level", "l",
|
||||||
|
"%s (debug, info, warning, error, critical)"
|
||||||
|
% (_("Enable logging"),),
|
||||||
|
"LEVEL", self.parse_log_level)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_log_level (arg):
|
||||||
|
|
||||||
|
try:
|
||||||
|
level = int (arg)
|
||||||
|
except ValueError:
|
||||||
|
level = {"off" : logging.NOTSET,
|
||||||
|
"none" : logging.NOTSET,
|
||||||
|
"debug" : logging.DEBUG,
|
||||||
|
"info" : logging.INFO,
|
||||||
|
"warning" : logging.WARNING,
|
||||||
|
"error" : logging.ERROR,
|
||||||
|
"critical" : logging.CRITICAL}.get (arg.strip ().lower ())
|
||||||
|
if level is None:
|
||||||
|
return logging.NOTSET
|
||||||
|
else:
|
||||||
|
return level
|
||||||
|
else:
|
||||||
|
if level < 0:
|
||||||
|
level = 0
|
||||||
|
elif level > 5:
|
||||||
|
level = 5
|
||||||
|
return {0 : logging.NOTSET,
|
||||||
|
1 : logging.DEBUG,
|
||||||
|
2 : logging.INFO,
|
||||||
|
3 : logging.WARNING,
|
||||||
|
4 : logging.ERROR,
|
||||||
|
5 : logging.CRITICAL}[level]
|
||||||
|
|
||||||
|
def _init_excepthooks ():
|
||||||
|
|
||||||
|
ExceptHookManager.setup ()
|
||||||
|
ExceptHookManager.register_handler (ExitOnInterruptExceptionHandler ())
|
||||||
|
|
||||||
|
def _init_paths (paths):
|
||||||
|
|
||||||
|
paths.ensure_setup ()
|
||||||
|
|
||||||
|
def _init_locale (gettext_domain = None):
|
||||||
|
|
||||||
|
if Paths.locale_dir and gettext_domain is not None:
|
||||||
|
try:
|
||||||
|
locale.setlocale (locale.LC_ALL, "")
|
||||||
|
except locale.Error, exc:
|
||||||
|
from warnings import warn
|
||||||
|
warn ("locale error: %s" % (exc,),
|
||||||
|
RuntimeWarning,
|
||||||
|
stacklevel = 2)
|
||||||
|
Paths.locale_dir = None
|
||||||
|
else:
|
||||||
|
gettext.bindtextdomain (gettext_domain, Paths.locale_dir)
|
||||||
|
gettext.textdomain (gettext_domain)
|
||||||
|
gettext.bind_textdomain_codeset (gettext_domain, "UTF-8")
|
||||||
|
|
||||||
|
def _init_options (option_parser = None):
|
||||||
|
|
||||||
|
if option_parser is None:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
option_parser.parse (sys.argv)
|
||||||
|
except OptionError, exc:
|
||||||
|
print >> sys.stderr, exc.args[0]
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
|
return option_parser.options
|
||||||
|
|
||||||
|
def _init_logging (level = logging.NOTSET):
|
||||||
|
|
||||||
|
logging.basicConfig (level = level,
|
||||||
|
format = '%(asctime)s.%(msecs)03d %(levelname)8s %(name)20s: %(message)s',
|
||||||
|
datefmt = '%H:%M:%S')
|
||||||
|
|
||||||
|
logger = logging.getLogger ("main")
|
||||||
|
logger.debug ("logging at level %s", logging.getLevelName (level))
|
||||||
|
logger.info ("using Python %i.%i.%i %s %i", *sys.version_info)
|
||||||
|
|
||||||
|
def main (option_parser = None, gettext_domain = None, paths = None):
|
||||||
|
|
||||||
|
# FIXME:
|
||||||
|
global Paths
|
||||||
|
Paths = paths
|
||||||
|
|
||||||
|
_init_excepthooks ()
|
||||||
|
_init_paths (paths)
|
||||||
|
_init_locale (gettext_domain)
|
||||||
|
options = _init_options (option_parser)
|
||||||
|
try:
|
||||||
|
log_level = options["log_level"]
|
||||||
|
except KeyError:
|
||||||
|
_init_logging ()
|
||||||
|
else:
|
||||||
|
_init_logging (log_level)
|
||||||
|
|
||||||
|
try:
|
||||||
|
options["main"] ()
|
||||||
|
finally:
|
||||||
|
logging.shutdown ()
|
19
debug-viewer/GstDebugViewer/Common/__init__.py
Normal file
19
debug-viewer/GstDebugViewer/Common/__init__.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer development utilities common module"""
|
||||||
|
|
324
debug-viewer/GstDebugViewer/Common/utils.py
Normal file
324
debug-viewer/GstDebugViewer/Common/utils.py
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Inspector - Multimedia system plugin introspection
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""Misc utilities."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import subprocess as _subprocess
|
||||||
|
|
||||||
|
class SingletonMeta (type):
|
||||||
|
|
||||||
|
def __init__ (cls, name, bases, dict_):
|
||||||
|
|
||||||
|
from weakref import WeakValueDictionary
|
||||||
|
|
||||||
|
super (SingletonMeta, cls).__init__ (name, bases, dict_)
|
||||||
|
|
||||||
|
cls._singleton_instances = WeakValueDictionary ()
|
||||||
|
|
||||||
|
def __call__ (cls, *a, **kw):
|
||||||
|
|
||||||
|
kw_key = tuple (sorted (kw.iteritems ()))
|
||||||
|
|
||||||
|
try:
|
||||||
|
obj = cls._singleton_instances[a + kw_key]
|
||||||
|
except KeyError:
|
||||||
|
obj = super (SingletonMeta, cls).__call__ (*a, **kw)
|
||||||
|
cls._singleton_instances[a + kw_key] = obj
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def gettext_cache ():
|
||||||
|
|
||||||
|
"""Return a callable object that operates like gettext.gettext, but is much
|
||||||
|
faster when a string is looked up more than once. This is very useful in
|
||||||
|
loops, where calling gettext.gettext can quickly become a major performance
|
||||||
|
bottleneck."""
|
||||||
|
|
||||||
|
from gettext import gettext
|
||||||
|
|
||||||
|
d = {}
|
||||||
|
|
||||||
|
def gettext_cache_access (s):
|
||||||
|
|
||||||
|
if not s in d:
|
||||||
|
d[s] = gettext (s)
|
||||||
|
return d[s]
|
||||||
|
|
||||||
|
return gettext_cache_access
|
||||||
|
|
||||||
|
class ClassProperty (property):
|
||||||
|
|
||||||
|
"Like the property class, but also invokes the getter for class access."
|
||||||
|
|
||||||
|
def __init__ (self, fget = None, fset = None, fdel = None, doc = None):
|
||||||
|
|
||||||
|
property.__init__ (self, fget, fset, fdel, doc)
|
||||||
|
|
||||||
|
self.__fget = fget
|
||||||
|
|
||||||
|
def __get__ (self, obj, obj_class = None):
|
||||||
|
|
||||||
|
ret = property.__get__ (self, obj, obj_class)
|
||||||
|
if ret == self:
|
||||||
|
return self.__fget (None)
|
||||||
|
else:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class _XDGClass (object):
|
||||||
|
|
||||||
|
"""Partial implementation of the XDG Base Directory specification v0.6.
|
||||||
|
|
||||||
|
http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html"""
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
self._add_base_dir ("DATA_HOME", "~/.local/share")
|
||||||
|
self._add_base_dir ("CONFIG_HOME", "~/.config")
|
||||||
|
self._add_base_dir ("CACHE_HOME", "~/.cache")
|
||||||
|
|
||||||
|
def _add_base_dir (self, name, default):
|
||||||
|
|
||||||
|
dir = os.environ.get ("XDG_%s" % (name,))
|
||||||
|
if not dir:
|
||||||
|
dir = os.path.expanduser (os.path.join (*default.split ("/")))
|
||||||
|
|
||||||
|
setattr (self, name, dir)
|
||||||
|
|
||||||
|
XDG = _XDGClass ()
|
||||||
|
|
||||||
|
class SaveWriteFile (object):
|
||||||
|
|
||||||
|
def __init__ (self, filename, mode = "wt"):
|
||||||
|
|
||||||
|
from tempfile import mkstemp
|
||||||
|
|
||||||
|
self.logger = logging.getLogger ("tempfile")
|
||||||
|
|
||||||
|
dir = os.path.dirname (filename)
|
||||||
|
base_name = os.path.basename (filename)
|
||||||
|
temp_prefix = "%s-tmp" % (base_name,)
|
||||||
|
|
||||||
|
if dir:
|
||||||
|
# Destination dir differs from current directory, ensure that it
|
||||||
|
# exists:
|
||||||
|
try:
|
||||||
|
os.makedirs (dir)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.clean_stale (dir, temp_prefix)
|
||||||
|
|
||||||
|
fd, temp_name = mkstemp (dir = dir, prefix = temp_prefix)
|
||||||
|
|
||||||
|
self.target_name = filename
|
||||||
|
self.temp_name = temp_name
|
||||||
|
self.real_file = os.fdopen (fd, mode)
|
||||||
|
|
||||||
|
def __enter__ (self):
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__ (self, *exc_args):
|
||||||
|
|
||||||
|
if exc_args == (None, None, None,):
|
||||||
|
self.close ()
|
||||||
|
else:
|
||||||
|
self.discard ()
|
||||||
|
|
||||||
|
def __del__ (self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.discard ()
|
||||||
|
except AttributeError:
|
||||||
|
# If __init__ failed, self has no real_file attribute.
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __close_real (self):
|
||||||
|
|
||||||
|
if self.real_file:
|
||||||
|
self.real_file.close ()
|
||||||
|
self.real_file = None
|
||||||
|
|
||||||
|
def clean_stale (self, dir, temp_prefix):
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
from glob import glob
|
||||||
|
|
||||||
|
now = time ()
|
||||||
|
pattern = os.path.join (dir, "%s*" % (temp_prefix,))
|
||||||
|
|
||||||
|
for temp_filename in glob (pattern):
|
||||||
|
mtime = os.stat (temp_filename).st_mtime
|
||||||
|
if now - mtime > 3600:
|
||||||
|
self.logger.info ("deleting stale temporary file %s",
|
||||||
|
temp_filename)
|
||||||
|
try:
|
||||||
|
os.unlink (temp_filename)
|
||||||
|
except EnvironmentError, exc:
|
||||||
|
self.logger.warning ("deleting stale temporary file "
|
||||||
|
"failed: %s", exc)
|
||||||
|
|
||||||
|
def tell (self, *a, **kw):
|
||||||
|
|
||||||
|
return self.real_file.tell (*a, **kw)
|
||||||
|
|
||||||
|
def write (self, *a, **kw):
|
||||||
|
|
||||||
|
return self.real_file.write (*a, **kw)
|
||||||
|
|
||||||
|
def close (self):
|
||||||
|
|
||||||
|
self.__close_real ()
|
||||||
|
|
||||||
|
if self.temp_name:
|
||||||
|
try:
|
||||||
|
os.rename (self.temp_name, self.target_name)
|
||||||
|
except OSError, exc:
|
||||||
|
import errno
|
||||||
|
if exc.errno == errno.EEXIST:
|
||||||
|
# We are probably on windows.
|
||||||
|
os.unlink (self.target_name)
|
||||||
|
os.rename (self.temp_name, self.target_name)
|
||||||
|
self.temp_name = None
|
||||||
|
|
||||||
|
def discard (self):
|
||||||
|
|
||||||
|
self.__close_real ()
|
||||||
|
|
||||||
|
if self.temp_name:
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.unlink (self.temp_name)
|
||||||
|
except EnvironmentError, exc:
|
||||||
|
self.logger.warning ("deleting temporary file failed: %s", exc)
|
||||||
|
self.temp_name = None
|
||||||
|
|
||||||
|
class TeeWriteFile (object):
|
||||||
|
|
||||||
|
# TODO Py2.5: Add context manager methods.
|
||||||
|
|
||||||
|
def __init__ (self, *file_objects):
|
||||||
|
|
||||||
|
self.files = list (file_objects)
|
||||||
|
|
||||||
|
def close (self):
|
||||||
|
|
||||||
|
for file in self.files:
|
||||||
|
file.close ()
|
||||||
|
|
||||||
|
def flush (self):
|
||||||
|
|
||||||
|
for file in self.files:
|
||||||
|
file.flush ()
|
||||||
|
|
||||||
|
def write (self, string):
|
||||||
|
|
||||||
|
for file in self.files:
|
||||||
|
file.write (string)
|
||||||
|
|
||||||
|
def writelines (self, lines):
|
||||||
|
|
||||||
|
for file in self.files:
|
||||||
|
file.writelines (lines)
|
||||||
|
|
||||||
|
class FixedPopen (_subprocess.Popen):
|
||||||
|
|
||||||
|
def __init__ (self, args, **kw):
|
||||||
|
|
||||||
|
# Unconditionally specify all descriptors as redirected, to
|
||||||
|
# work around Python bug #1358527 (which is triggered for
|
||||||
|
# console-less applications on Windows).
|
||||||
|
|
||||||
|
close = []
|
||||||
|
|
||||||
|
for name in ("stdin", "stdout", "stderr",):
|
||||||
|
target = kw.get (name)
|
||||||
|
if not target:
|
||||||
|
kw[name] = _subprocess.PIPE
|
||||||
|
close.append (name)
|
||||||
|
|
||||||
|
_subprocess.Popen.__init__ (self, args, **kw)
|
||||||
|
|
||||||
|
for name in close:
|
||||||
|
fp = getattr (self, name)
|
||||||
|
fp.close ()
|
||||||
|
setattr (self, name, None)
|
||||||
|
|
||||||
|
class DevhelpError (EnvironmentError):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DevhelpUnavailableError (DevhelpError):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class DevhelpClient (object):
|
||||||
|
|
||||||
|
def available (self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.version ()
|
||||||
|
except DevhelpUnavailableError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def version (self):
|
||||||
|
|
||||||
|
return self._invoke ("--version")
|
||||||
|
|
||||||
|
def search (self, entry):
|
||||||
|
|
||||||
|
self._invoke_no_interact ("-s", entry)
|
||||||
|
|
||||||
|
def _check_os_error (self, exc):
|
||||||
|
|
||||||
|
import errno
|
||||||
|
if exc.errno == errno.ENOENT:
|
||||||
|
raise DevhelpUnavailableError ()
|
||||||
|
|
||||||
|
def _invoke (self, *args):
|
||||||
|
|
||||||
|
from subprocess import PIPE
|
||||||
|
|
||||||
|
try:
|
||||||
|
proc = FixedPopen (("devhelp",) + args,
|
||||||
|
stdout = PIPE)
|
||||||
|
except OSError, exc:
|
||||||
|
self._check_os_error (exc)
|
||||||
|
raise
|
||||||
|
|
||||||
|
out, err = proc.communicate ()
|
||||||
|
|
||||||
|
if proc.returncode is not None and proc.returncode != 0:
|
||||||
|
raise DevhelpError ("devhelp exited with status %i"
|
||||||
|
% (proc.returncode,))
|
||||||
|
return out
|
||||||
|
|
||||||
|
def _invoke_no_interact (self, *args):
|
||||||
|
|
||||||
|
from subprocess import PIPE
|
||||||
|
|
||||||
|
try:
|
||||||
|
proc = FixedPopen (("devhelp",) + args)
|
||||||
|
except OSError, exc:
|
||||||
|
self._check_os_error (exc)
|
||||||
|
raise
|
||||||
|
|
247
debug-viewer/GstDebugViewer/Data.py
Normal file
247
debug-viewer/GstDebugViewer/Data.py
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Debug Viewer
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer debug viewer data module"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
|
# Nanosecond resolution (like gst.SECOND)
|
||||||
|
SECOND = 1000000000
|
||||||
|
|
||||||
|
def time_args (ts):
|
||||||
|
|
||||||
|
secs = ts // SECOND
|
||||||
|
|
||||||
|
return "%i:%02i:%02i.%09i" % (secs // 60**2,
|
||||||
|
secs // 60 % 60,
|
||||||
|
secs % 60,
|
||||||
|
ts % SECOND,)
|
||||||
|
|
||||||
|
def time_args_no_hours (ts):
|
||||||
|
|
||||||
|
secs = ts // SECOND
|
||||||
|
|
||||||
|
return "%02i:%02i.%09i" % (secs // 60,
|
||||||
|
secs % 60,
|
||||||
|
ts % SECOND,)
|
||||||
|
|
||||||
|
def parse_time (st):
|
||||||
|
|
||||||
|
"""Parse time strings that look like "0:00:00.0000000"."""
|
||||||
|
|
||||||
|
h, m, s = st.split (":")
|
||||||
|
secs, subsecs = s.split (".")
|
||||||
|
|
||||||
|
return (long ((int (h) * 60**2 + int (m) * 60) * SECOND) +
|
||||||
|
long (secs) * SECOND + long (subsecs))
|
||||||
|
|
||||||
|
class DebugLevel (int):
|
||||||
|
|
||||||
|
__names = ["NONE", "ERROR", "WARNING", "INFO", "DEBUG", "LOG"]
|
||||||
|
__instances = {}
|
||||||
|
|
||||||
|
def __new__ (cls, level):
|
||||||
|
|
||||||
|
try:
|
||||||
|
level_int = int (level)
|
||||||
|
except (ValueError, TypeError,):
|
||||||
|
try:
|
||||||
|
level_int = cls.__names.index (level.upper ())
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError ("no debug level named %r" % (level,))
|
||||||
|
if level_int in cls.__instances:
|
||||||
|
return cls.__instances[level_int]
|
||||||
|
else:
|
||||||
|
new_instance = int.__new__ (cls, level_int)
|
||||||
|
new_instance.name = cls.__names[level_int]
|
||||||
|
cls.__instances[level_int] = new_instance
|
||||||
|
return new_instance
|
||||||
|
|
||||||
|
def __repr__ (self):
|
||||||
|
|
||||||
|
return "<%s %s (%i)>" % (type (self).__name__, self.__names[self], self,)
|
||||||
|
|
||||||
|
def higher_level (self):
|
||||||
|
|
||||||
|
if self == len (self.__names) - 1:
|
||||||
|
raise ValueError ("already the highest debug level")
|
||||||
|
|
||||||
|
return DebugLevel (self + 1)
|
||||||
|
|
||||||
|
def lower_level (self):
|
||||||
|
|
||||||
|
if self == 0:
|
||||||
|
raise ValueError ("already the lowest debug level")
|
||||||
|
|
||||||
|
return DebugLevel (self - 1)
|
||||||
|
|
||||||
|
DebugLevelNone = DebugLevel ("NONE")
|
||||||
|
DebugLevelError = DebugLevel ("ERROR")
|
||||||
|
DebugLevelWarning = DebugLevel ("WARNING")
|
||||||
|
DebugLevelInfo = DebugLevel ("INFO")
|
||||||
|
DebugLevelDebug = DebugLevel ("DEBUG")
|
||||||
|
DebugLevelLog = DebugLevel ("LOG")
|
||||||
|
|
||||||
|
# For stripping color codes:
|
||||||
|
_escape = re.compile ("\x1b\\[[0-9;]*m")
|
||||||
|
def strip_escape (s):
|
||||||
|
|
||||||
|
return _escape.sub ("", s)
|
||||||
|
|
||||||
|
def default_log_line_regex_ ():
|
||||||
|
|
||||||
|
# "DEBUG "
|
||||||
|
LEVEL = "([A-Z]+) +"
|
||||||
|
# "0x8165430 "
|
||||||
|
THREAD = r"(0x[0-9a-f]+) +" #r"\((0x[0-9a-f]+) - "
|
||||||
|
# "0:00:00.777913000 "
|
||||||
|
#TIME = r"([0-9]+:[0-9][0-9]:[0-9][0-9]\.[0-9]+) +"
|
||||||
|
TIME = " +" # Only eating whitespace before PID away, we parse timestamps
|
||||||
|
# without regex.
|
||||||
|
CATEGORY = "([A-Za-z_-]+) +" # "GST_REFCOUNTING ", "flacdec "
|
||||||
|
# " 3089 "
|
||||||
|
PID = r"([0-9]+) +"
|
||||||
|
FILENAME = r"([^:]+):"
|
||||||
|
LINE = r"([0-9]+):"
|
||||||
|
FUNCTION = "([A-Za-z0-9_]+):"
|
||||||
|
# FIXME: When non-g(st)object stuff is logged with *_OBJECT (like
|
||||||
|
# buffers!), the address is printed *without* <> brackets!
|
||||||
|
OBJECT = "(?:<([^>]+)>)?"
|
||||||
|
MESSAGE = " (.+)"
|
||||||
|
|
||||||
|
expressions = [TIME, PID, THREAD, LEVEL, CATEGORY, FILENAME, LINE, FUNCTION,
|
||||||
|
OBJECT, MESSAGE]
|
||||||
|
## expressions = [LEVEL, THREAD, TIME, CATEGORY, PID, FILENAME, LINE,
|
||||||
|
## FUNCTION, OBJECT, MESSAGE]
|
||||||
|
|
||||||
|
return expressions
|
||||||
|
|
||||||
|
def default_log_line_regex ():
|
||||||
|
|
||||||
|
expressions = default_log_line_regex_ ()
|
||||||
|
return re.compile ("".join (expressions))
|
||||||
|
|
||||||
|
class Producer (object):
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
self.consumers = []
|
||||||
|
|
||||||
|
def have_load_started (self):
|
||||||
|
|
||||||
|
for consumer in self.consumers:
|
||||||
|
consumer.handle_load_started ()
|
||||||
|
|
||||||
|
def have_load_finished (self):
|
||||||
|
|
||||||
|
for consumer in self.consumers:
|
||||||
|
consumer.handle_load_finished ()
|
||||||
|
|
||||||
|
class LineCache (Producer):
|
||||||
|
|
||||||
|
_lines_per_iteration = 1000
|
||||||
|
|
||||||
|
def __init__ (self, fileobj, dispatcher):
|
||||||
|
|
||||||
|
Producer.__init__ (self)
|
||||||
|
|
||||||
|
self.logger = logging.getLogger ("linecache")
|
||||||
|
|
||||||
|
self.offsets = []
|
||||||
|
self.dispatcher = dispatcher
|
||||||
|
|
||||||
|
import mmap
|
||||||
|
self.__fileobj = mmap.mmap (fileobj.fileno (), 0, prot = mmap.PROT_READ)
|
||||||
|
|
||||||
|
self.__fileobj.seek (0, 2)
|
||||||
|
self.__file_size = self.__fileobj.tell ()
|
||||||
|
self.__fileobj.seek (0)
|
||||||
|
|
||||||
|
def start_loading (self):
|
||||||
|
|
||||||
|
self.logger.debug ("dispatching load process")
|
||||||
|
self.have_load_started ()
|
||||||
|
self.dispatcher (self.__process ())
|
||||||
|
|
||||||
|
def get_progress (self):
|
||||||
|
|
||||||
|
return float (self.__fileobj.tell ()) / self.__file_size
|
||||||
|
|
||||||
|
def __process (self):
|
||||||
|
|
||||||
|
offsets = self.offsets
|
||||||
|
readline = self.__fileobj.readline
|
||||||
|
tell = self.__fileobj.tell
|
||||||
|
|
||||||
|
self.__fileobj.seek (0)
|
||||||
|
limit = self._lines_per_iteration
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
offset = tell ()
|
||||||
|
line = readline ()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
if not line.strip ():
|
||||||
|
# Ignore empty lines, especially the one established by the
|
||||||
|
# final newline at the end:
|
||||||
|
continue
|
||||||
|
# FIXME: We need to handle foreign lines separately!
|
||||||
|
if line[1] != ":" or line[4] != ":" or line[7] != ".":
|
||||||
|
# No timestamp at start, ignore line:
|
||||||
|
continue
|
||||||
|
offsets.append (offset)
|
||||||
|
i += 1
|
||||||
|
if i == limit:
|
||||||
|
yield True
|
||||||
|
|
||||||
|
self.have_load_finished ()
|
||||||
|
yield False
|
||||||
|
|
||||||
|
class LogFile (Producer):
|
||||||
|
|
||||||
|
def __init__ (self, filename, dispatcher):
|
||||||
|
|
||||||
|
Producer.__init__ (self)
|
||||||
|
|
||||||
|
self.logger = logging.getLogger ("logfile")
|
||||||
|
|
||||||
|
self.fileobj = file (filename, "rb")
|
||||||
|
self.line_cache = LineCache (self.fileobj, dispatcher)
|
||||||
|
self.line_cache.consumers.append (self)
|
||||||
|
|
||||||
|
def start_loading (self):
|
||||||
|
|
||||||
|
self.logger.debug ("starting load")
|
||||||
|
self.line_cache.start_loading ()
|
||||||
|
|
||||||
|
def get_load_progress (self):
|
||||||
|
|
||||||
|
return self.line_cache.get_progress ()
|
||||||
|
|
||||||
|
def handle_load_started (self):
|
||||||
|
|
||||||
|
# Chain up to our consumers:
|
||||||
|
self.have_load_started ()
|
||||||
|
|
||||||
|
def handle_load_finished (self):
|
||||||
|
|
||||||
|
# Chain up to our consumers:
|
||||||
|
self.have_load_finished ()
|
||||||
|
|
1196
debug-viewer/GstDebugViewer/GUI.py
Executable file
1196
debug-viewer/GstDebugViewer/GUI.py
Executable file
File diff suppressed because it is too large
Load diff
75
debug-viewer/GstDebugViewer/Main.py
Normal file
75
debug-viewer/GstDebugViewer/Main.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Debug Viewer
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer debug viewer main module"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from gettext import gettext as _, ngettext
|
||||||
|
|
||||||
|
import GstDebugViewer.Common.Main
|
||||||
|
Common = GstDebugViewer.Common
|
||||||
|
|
||||||
|
GETTEXT_DOMAIN = "gst-debug-viewer"
|
||||||
|
|
||||||
|
def main_version ():
|
||||||
|
|
||||||
|
from GstDebugViewer import version
|
||||||
|
|
||||||
|
print "GStreamer Debug Viewer %s" % (version,)
|
||||||
|
|
||||||
|
class Paths (Common.Main.PathsProgramBase):
|
||||||
|
|
||||||
|
program_name = "gst-debug-viewer"
|
||||||
|
|
||||||
|
class OptionParser (Common.Main.LogOptionParser):
|
||||||
|
|
||||||
|
def __init__ (self, options):
|
||||||
|
|
||||||
|
Common.Main.LogOptionParser.__init__ (self, options)
|
||||||
|
|
||||||
|
options["main"] = None
|
||||||
|
|
||||||
|
self.add_option ("version", None, _("Display version and exit"))
|
||||||
|
|
||||||
|
def get_parameter_string (self):
|
||||||
|
|
||||||
|
return _("- Display and analyze debug log files")
|
||||||
|
|
||||||
|
def handle_parse_complete (self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = self.options["version"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
main_version ()
|
||||||
|
sys.exit (0)
|
||||||
|
|
||||||
|
if self.options["main"] is None:
|
||||||
|
import GUI
|
||||||
|
self.options["main"] = GUI.main
|
||||||
|
|
||||||
|
def main ():
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
parser = OptionParser (options)
|
||||||
|
|
||||||
|
Common.Main.main (option_parser = parser,
|
||||||
|
gettext_domain = GETTEXT_DOMAIN,
|
||||||
|
paths = Paths)
|
42
debug-viewer/GstDebugViewer/Plugins/ColorizeRows.py
Normal file
42
debug-viewer/GstDebugViewer/Plugins/ColorizeRows.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
from GstDebugViewer.Plugins import FeatureBase, PluginBase
|
||||||
|
|
||||||
|
class ColorizeLevels (FeatureBase):
|
||||||
|
|
||||||
|
def attach (self, window):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def detach (self, window):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class LevelColorSentinel (object):
|
||||||
|
|
||||||
|
def processor (self, proc):
|
||||||
|
|
||||||
|
for row in proc:
|
||||||
|
|
||||||
|
yield None
|
||||||
|
|
||||||
|
class ColorizeCategories (FeatureBase):
|
||||||
|
|
||||||
|
def attach (self, window):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def detach (self, window):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class CategoryColorSentinel (object):
|
||||||
|
|
||||||
|
def processor (self):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Plugin (PluginBase):
|
||||||
|
|
||||||
|
features = [ColorizeLevels, ColorizeCategories]
|
||||||
|
|
||||||
|
|
322
debug-viewer/GstDebugViewer/Plugins/LineFrequency.py
Normal file
322
debug-viewer/GstDebugViewer/Plugins/LineFrequency.py
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from GstDebugViewer.Plugins import *
|
||||||
|
|
||||||
|
import cairo
|
||||||
|
import gtk
|
||||||
|
|
||||||
|
def iter_model_reversed (model):
|
||||||
|
|
||||||
|
count = model.iter_n_children (None)
|
||||||
|
for i in xrange (count - 1, 0, -1):
|
||||||
|
yield model[i]
|
||||||
|
|
||||||
|
class LineFrequencySentinel (object):
|
||||||
|
|
||||||
|
def __init__ (self, model):
|
||||||
|
|
||||||
|
self.model = model
|
||||||
|
|
||||||
|
def _search_ts (self, target_ts, first_index, last_index):
|
||||||
|
|
||||||
|
model_get = self.model.get
|
||||||
|
model_iter_nth_child = self.model.iter_nth_child
|
||||||
|
col_id = self.model.COL_TIME
|
||||||
|
|
||||||
|
while True:
|
||||||
|
middle = (last_index - first_index) // 2 + first_index
|
||||||
|
if middle == first_index:
|
||||||
|
return last_index
|
||||||
|
ts = model_get (model_iter_nth_child (None, middle), col_id)[0]
|
||||||
|
if ts < target_ts:
|
||||||
|
first_index = middle + 1
|
||||||
|
elif ts > target_ts:
|
||||||
|
last_index = middle - 1
|
||||||
|
else:
|
||||||
|
return middle
|
||||||
|
|
||||||
|
def run_for (self, n):
|
||||||
|
|
||||||
|
if n == 0:
|
||||||
|
raise ValueError ("illegal value for n")
|
||||||
|
|
||||||
|
model = self.model
|
||||||
|
result = []
|
||||||
|
|
||||||
|
last_ts = None
|
||||||
|
for row in iter_model_reversed (self.model):
|
||||||
|
last_ts = row[model.COL_TIME]
|
||||||
|
if last_ts:
|
||||||
|
last_index = row.path[0]
|
||||||
|
break
|
||||||
|
|
||||||
|
if last_ts is None:
|
||||||
|
return result
|
||||||
|
|
||||||
|
step = int (float (last_ts) / float (n))
|
||||||
|
|
||||||
|
first_index = 0
|
||||||
|
target_ts = step
|
||||||
|
old_found = 0
|
||||||
|
while target_ts < last_ts:
|
||||||
|
found = self._search_ts (target_ts, first_index, last_index)
|
||||||
|
result.append (found - old_found)
|
||||||
|
old_found = found
|
||||||
|
first_index = found
|
||||||
|
target_ts += step
|
||||||
|
|
||||||
|
## count = 0
|
||||||
|
## limit = step
|
||||||
|
## for row in self.model:
|
||||||
|
## ts = row[model.COL_TIME]
|
||||||
|
## if ts is None:
|
||||||
|
## continue
|
||||||
|
## if ts > limit:
|
||||||
|
## limit += step
|
||||||
|
## result.append (count)
|
||||||
|
## count = 0
|
||||||
|
## count += 1
|
||||||
|
|
||||||
|
return (step, result,)
|
||||||
|
|
||||||
|
class LineFrequencyWidget (gtk.DrawingArea):
|
||||||
|
|
||||||
|
__gtype_name__ = "LineFrequencyWidget"
|
||||||
|
|
||||||
|
def __init__ (self, sentinel = None):
|
||||||
|
|
||||||
|
gtk.DrawingArea.__init__ (self)
|
||||||
|
|
||||||
|
self.logger = logging.getLogger ("ui.density-widget")
|
||||||
|
|
||||||
|
self.sentinel = sentinel
|
||||||
|
self.sentinel_step = None
|
||||||
|
self.sentinel_data = None
|
||||||
|
self.__configure_id = None
|
||||||
|
self.connect ("expose-event", self.__handle_expose_event)
|
||||||
|
self.connect ("configure-event", self.__handle_configure_event)
|
||||||
|
self.connect ("size-request", self.__handle_size_request)
|
||||||
|
|
||||||
|
def set_sentinel (self, sentinel):
|
||||||
|
|
||||||
|
self.sentinel = sentinel
|
||||||
|
self.__redraw ()
|
||||||
|
|
||||||
|
def __redraw (self):
|
||||||
|
|
||||||
|
if not self.props.visible:
|
||||||
|
return
|
||||||
|
|
||||||
|
x, y, w, h = self.get_allocation ()
|
||||||
|
self.offscreen = gtk.gdk.Pixmap (self.window, w, h, -1)
|
||||||
|
|
||||||
|
self.__draw (self.offscreen)
|
||||||
|
|
||||||
|
self.__update ()
|
||||||
|
|
||||||
|
def __update (self):
|
||||||
|
|
||||||
|
if not self.props.visible:
|
||||||
|
return
|
||||||
|
|
||||||
|
gc = gtk.gdk.GC (self.window)
|
||||||
|
self.window.draw_drawable (gc, self.offscreen, 0, 0, 0, 0, -1, -1)
|
||||||
|
|
||||||
|
def update_position (self, start_ts, end_ts):
|
||||||
|
|
||||||
|
self.__update ()
|
||||||
|
|
||||||
|
position1 = int (float (start_ts) / self.sentinel_step)
|
||||||
|
position2 = int (float (end_ts) / self.sentinel_step)
|
||||||
|
|
||||||
|
ctx = self.window.cairo_create ()
|
||||||
|
x, y, w, h = self.get_allocation ()
|
||||||
|
|
||||||
|
line_width = position2 - position1
|
||||||
|
ctx.set_source_rgba (1., 0., 0., .5)
|
||||||
|
if line_width <= 1:
|
||||||
|
ctx.set_line_width (1.)
|
||||||
|
ctx.move_to (position1 + .5, 0)
|
||||||
|
ctx.line_to (position1 + .5, h)
|
||||||
|
ctx.stroke ()
|
||||||
|
else:
|
||||||
|
ctx.rectangle (position1, 0, line_width, h)
|
||||||
|
ctx.fill ()
|
||||||
|
|
||||||
|
def __draw (self, drawable):
|
||||||
|
|
||||||
|
ctx = drawable.cairo_create ()
|
||||||
|
x, y, w, h = self.get_allocation ()
|
||||||
|
ctx.set_line_width (0.)
|
||||||
|
ctx.rectangle (0, 0, w, h)
|
||||||
|
ctx.set_source_rgb (1., 1., 1.)
|
||||||
|
ctx.fill ()
|
||||||
|
ctx.new_path ()
|
||||||
|
|
||||||
|
if self.sentinel_data is None and self.sentinel:
|
||||||
|
if w > 15:
|
||||||
|
self.logger.debug ("running sentinel for width %i", w)
|
||||||
|
self.sentinel_step, self.sentinel_data = self.sentinel.run_for (w)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.sentinel_data is None:
|
||||||
|
self.logger.debug ("not redrawing: no sentinel set")
|
||||||
|
return
|
||||||
|
|
||||||
|
from operator import add
|
||||||
|
maximum = max (self.sentinel_data)
|
||||||
|
heights = [h * float (d) / maximum for d in self.sentinel_data]
|
||||||
|
ctx.move_to (0, h)
|
||||||
|
ctx.set_source_rgb (0., 0., 0.)
|
||||||
|
for i in range (len (heights)):
|
||||||
|
ctx.line_to (i - .5, h - heights[i] + .5)
|
||||||
|
#ctx.rectangle (i - .5, h - heights[i] + .5, i + 1, h)
|
||||||
|
|
||||||
|
ctx.line_to (i, h)
|
||||||
|
ctx.close_path ()
|
||||||
|
|
||||||
|
ctx.fill ()
|
||||||
|
|
||||||
|
def __handle_expose_event (self, self_, event):
|
||||||
|
|
||||||
|
self.__redraw ()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __handle_configure_event (self, self_, event):
|
||||||
|
|
||||||
|
if event.width < 16:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.sentinel:
|
||||||
|
self.sentinel_step, self.sentinel_data = self.sentinel.run_for (event.width)
|
||||||
|
|
||||||
|
# FIXME: Is this done automatically?
|
||||||
|
self.queue_draw ()
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __handle_size_request (self, self_, req):
|
||||||
|
|
||||||
|
# FIXME:
|
||||||
|
req.height = 64
|
||||||
|
|
||||||
|
class LineFrequencyFeature (FeatureBase):
|
||||||
|
|
||||||
|
state_section_name = "line-frequency-display"
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
self.action_group = gtk.ActionGroup ("LineFrequencyActions")
|
||||||
|
self.action_group.add_toggle_actions ([("show-line-frequency",
|
||||||
|
None, _("Line _Density"))])
|
||||||
|
|
||||||
|
def attach (self, window):
|
||||||
|
|
||||||
|
self.log_model = window.log_model
|
||||||
|
self.log_view = window.log_view
|
||||||
|
|
||||||
|
ui = window.ui_manager
|
||||||
|
|
||||||
|
ui.insert_action_group (self.action_group, 0)
|
||||||
|
|
||||||
|
self.merge_id = ui.new_merge_id ()
|
||||||
|
ui.add_ui (self.merge_id, "/menubar/ViewMenu/ViewMenuAdditions",
|
||||||
|
"ViewLineFrequency", "show-line-frequency",
|
||||||
|
gtk.UI_MANAGER_MENUITEM, False)
|
||||||
|
|
||||||
|
box = window.get_top_attach_point ()
|
||||||
|
|
||||||
|
self.density_display = LineFrequencyWidget ()
|
||||||
|
self.density_display.add_events (gtk.gdk.ALL_EVENTS_MASK) # FIXME
|
||||||
|
self.density_display.connect ("button-press-event", self.handle_density_button_press_event)
|
||||||
|
self.density_display.connect ("motion-notify-event", self.handle_density_motion_notify_event)
|
||||||
|
box.pack_start (self.density_display, False, False, 0)
|
||||||
|
self.density_display.hide ()
|
||||||
|
|
||||||
|
window.widgets.log_view_scrolled_window.props.vadjustment.connect ("value-changed",
|
||||||
|
self.handle_log_view_adjustment_value_changed)
|
||||||
|
|
||||||
|
handler = self.handle_show_action_toggled
|
||||||
|
self.action_group.get_action ("show-line-frequency").connect ("toggled", handler)
|
||||||
|
|
||||||
|
window.sentinels.append (self.sentinel_process)
|
||||||
|
|
||||||
|
def detach (self, window):
|
||||||
|
|
||||||
|
window.sentinels.remove (self.sentinel_process)
|
||||||
|
|
||||||
|
window.ui_manager.remove_ui (self.merge_id)
|
||||||
|
self.merge_id = None
|
||||||
|
|
||||||
|
# FIXME: Remove action group from ui manager!
|
||||||
|
|
||||||
|
self.density_display.destroy ()
|
||||||
|
self.density_display = None
|
||||||
|
|
||||||
|
def sentinel_process (self):
|
||||||
|
|
||||||
|
if self.action_group.get_action ("show-line-frequency").props.active:
|
||||||
|
sentinel = LineDensitySentinel (self.log_model)
|
||||||
|
self.density_display.set_sentinel (sentinel)
|
||||||
|
|
||||||
|
def handle_log_view_adjustment_value_changed (self, adj):
|
||||||
|
|
||||||
|
# FIXME: If not visible, disconnect this handler!
|
||||||
|
if not self.density_display.props.visible:
|
||||||
|
return
|
||||||
|
|
||||||
|
start_path, end_path = self.log_view.get_visible_range ()
|
||||||
|
ts1 = self.log_model.get (self.log_model.get_iter (start_path),
|
||||||
|
self.log_model.COL_TIME)[0]
|
||||||
|
ts2 = self.log_model.get (self.log_model.get_iter (end_path),
|
||||||
|
self.log_model.COL_TIME)[0]
|
||||||
|
self.density_display.update_position (ts1, ts2)
|
||||||
|
|
||||||
|
def handle_show_action_toggled (self, action):
|
||||||
|
|
||||||
|
show = action.props.active
|
||||||
|
|
||||||
|
if show:
|
||||||
|
self.density_display.show ()
|
||||||
|
if self.density_display.sentinel is None:
|
||||||
|
sentinel = LineFrequencySentinel (self.log_model)
|
||||||
|
self.density_display.set_sentinel (sentinel)
|
||||||
|
else:
|
||||||
|
self.density_display.hide ()
|
||||||
|
|
||||||
|
def handle_density_button_press_event (self, widget, event):
|
||||||
|
|
||||||
|
if event.button != 1:
|
||||||
|
return True
|
||||||
|
|
||||||
|
pos = int (event.x)
|
||||||
|
self.goto_density (pos)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def handle_density_motion_notify_event (self, widget, event):
|
||||||
|
|
||||||
|
if not event.state & gtk.gdk.BUTTON1_MASK:
|
||||||
|
return True
|
||||||
|
|
||||||
|
pos = int (event.x)
|
||||||
|
self.goto_density (pos)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def goto_density (self, pos):
|
||||||
|
|
||||||
|
data = self.density_display.sentinel_data
|
||||||
|
if not data:
|
||||||
|
return True
|
||||||
|
count = 0
|
||||||
|
for i in range (pos):
|
||||||
|
count += data[i]
|
||||||
|
|
||||||
|
row = self.log_model[count]
|
||||||
|
self.log_view.scroll_to_cell ((count,), use_align = True, row_align = .5)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
class Plugin (PluginBase):
|
||||||
|
|
||||||
|
features = [LineFrequencyFeature]
|
42
debug-viewer/GstDebugViewer/Plugins/__init__.py
Normal file
42
debug-viewer/GstDebugViewer/Plugins/__init__.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
__all__ = ["_", "FeatureBase", "PluginBase"]
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
from gettext import gettext as _
|
||||||
|
|
||||||
|
def load (paths = ()):
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
for plugin_module in _load_plugins (path):
|
||||||
|
yield plugin_module.Plugin
|
||||||
|
|
||||||
|
def _load_plugins (path):
|
||||||
|
|
||||||
|
import imp, glob
|
||||||
|
|
||||||
|
files = glob.glob (os.path.join (path, "*.py"))
|
||||||
|
|
||||||
|
for filename in files:
|
||||||
|
|
||||||
|
name = os.path.basename (os.path.splitext (filename)[0])
|
||||||
|
if name == "__init__":
|
||||||
|
continue
|
||||||
|
fp, pathname, description = imp.find_module (name, [path])
|
||||||
|
module = imp.load_module (name, fp, pathname, description)
|
||||||
|
yield module
|
||||||
|
|
||||||
|
class FeatureBase (object):
|
||||||
|
|
||||||
|
state_section_name = None
|
||||||
|
|
||||||
|
def register_lazy_sentinel (self, sentinel):
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
class PluginBase (object):
|
||||||
|
|
||||||
|
features = ()
|
||||||
|
|
||||||
|
def __init__ (self):
|
||||||
|
|
||||||
|
pass
|
24
debug-viewer/GstDebugViewer/__init__.py
Normal file
24
debug-viewer/GstDebugViewer/__init__.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Debug Viewer
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
version = "0.1"
|
||||||
|
|
||||||
|
__version__ = version
|
||||||
|
|
||||||
|
from GstDebugViewer.Main import Paths, main as run
|
502
debug-viewer/data/gst-debug-viewer.glade
Normal file
502
debug-viewer/data/gst-debug-viewer.glade
Normal file
|
@ -0,0 +1,502 @@
|
||||||
|
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||||
|
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||||
|
|
||||||
|
<glade-interface>
|
||||||
|
<requires lib="gnome"/>
|
||||||
|
|
||||||
|
<widget class="GtkWindow" id="main_window">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">GStreamer Debug Viewer</property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||||
|
<property name="modal">False</property>
|
||||||
|
<property name="default_width">640</property>
|
||||||
|
<property name="default_height">480</property>
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="decorated">True</property>
|
||||||
|
<property name="skip_taskbar_hint">False</property>
|
||||||
|
<property name="skip_pager_hint">False</property>
|
||||||
|
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||||
|
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||||
|
<property name="focus_on_map">True</property>
|
||||||
|
<property name="urgency_hint">False</property>
|
||||||
|
<signal name="destroy" handler="handle_main_window_destroy" last_modification_time="Thu, 05 Oct 2006 20:05:35 GMT"/>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox_main">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkScrolledWindow" id="log_view_scrolled_window">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||||
|
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||||
|
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||||
|
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkTreeView" id="log_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="headers_visible">True</property>
|
||||||
|
<property name="rules_hint">True</property>
|
||||||
|
<property name="reorderable">True</property>
|
||||||
|
<property name="enable_search">True</property>
|
||||||
|
<property name="fixed_height_mode">False</property>
|
||||||
|
<property name="hover_selection">False</property>
|
||||||
|
<property name="hover_expand">False</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">GTK_PACK_END</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
<widget class="GtkAboutDialog" id="about_dialog">
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="name" translatable="yes">GStreamer Debug Viewer</property>
|
||||||
|
<property name="copyright" translatable="yes">Copyright © 2007 René Stadler</property>
|
||||||
|
<property name="comments" translatable="yes">View and analyze GStreamer debug files</property>
|
||||||
|
<property name="license"> GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
|
</property>
|
||||||
|
<property name="wrap_license">False</property>
|
||||||
|
<property name="authors">René Stadler <mail@renestadler.de></property>
|
||||||
|
<property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property>
|
||||||
|
<property name="logo">gst-debug-viewer.png</property>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
<widget class="GtkDialog" id="progress_dialog">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">Loading log...</property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="resizable">False</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="decorated">True</property>
|
||||||
|
<property name="skip_taskbar_hint">False</property>
|
||||||
|
<property name="skip_pager_hint">False</property>
|
||||||
|
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||||
|
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||||
|
<property name="focus_on_map">True</property>
|
||||||
|
<property name="urgency_hint">False</property>
|
||||||
|
<property name="has_separator">False</property>
|
||||||
|
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<widget class="GtkVBox" id="dialog-vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="button2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label">gtk-cancel</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="response_id">-6</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">GTK_PACK_END</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox3">
|
||||||
|
<property name="border_width">6</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkProgressBar" id="progress_bar">
|
||||||
|
<property name="width_request">250</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
|
||||||
|
<property name="fraction">0</property>
|
||||||
|
<property name="pulse_step">0.10000000149</property>
|
||||||
|
<property name="text" translatable="yes">Loading file</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">12</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
</glade-interface>
|
502
debug-viewer/data/gst-debug-viewer.glade.bak
Normal file
502
debug-viewer/data/gst-debug-viewer.glade.bak
Normal file
|
@ -0,0 +1,502 @@
|
||||||
|
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||||
|
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||||
|
|
||||||
|
<glade-interface>
|
||||||
|
<requires lib="gnome"/>
|
||||||
|
|
||||||
|
<widget class="GtkWindow" id="main_window">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">GStreamer Debug Viewer</property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||||
|
<property name="modal">False</property>
|
||||||
|
<property name="default_width">640</property>
|
||||||
|
<property name="default_height">480</property>
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="decorated">True</property>
|
||||||
|
<property name="skip_taskbar_hint">False</property>
|
||||||
|
<property name="skip_pager_hint">False</property>
|
||||||
|
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||||
|
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||||
|
<property name="focus_on_map">True</property>
|
||||||
|
<property name="urgency_hint">False</property>
|
||||||
|
<signal name="destroy" handler="handle_main_window_destroy" last_modification_time="Thu, 05 Oct 2006 20:05:35 GMT"/>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox_main">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||||
|
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||||
|
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||||
|
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkTreeView" id="log_view">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="headers_visible">True</property>
|
||||||
|
<property name="rules_hint">True</property>
|
||||||
|
<property name="reorderable">True</property>
|
||||||
|
<property name="enable_search">True</property>
|
||||||
|
<property name="fixed_height_mode">False</property>
|
||||||
|
<property name="hover_selection">False</property>
|
||||||
|
<property name="hover_expand">False</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">GTK_PACK_END</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
<widget class="GtkAboutDialog" id="about_dialog">
|
||||||
|
<property name="border_width">5</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="name" translatable="yes">GStreamer Debug Viewer</property>
|
||||||
|
<property name="copyright" translatable="yes">Copyright © 2007 René Stadler</property>
|
||||||
|
<property name="comments" translatable="yes">View and analyze GStreamer debug files</property>
|
||||||
|
<property name="license"> GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
|
</property>
|
||||||
|
<property name="wrap_license">False</property>
|
||||||
|
<property name="authors">René Stadler <mail@renestadler.de></property>
|
||||||
|
<property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property>
|
||||||
|
<property name="logo">gst-debug-viewer.png</property>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
<widget class="GtkDialog" id="progress_dialog">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">Loading log...</property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="resizable">False</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="decorated">True</property>
|
||||||
|
<property name="skip_taskbar_hint">False</property>
|
||||||
|
<property name="skip_pager_hint">False</property>
|
||||||
|
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||||
|
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||||
|
<property name="focus_on_map">True</property>
|
||||||
|
<property name="urgency_hint">False</property>
|
||||||
|
<property name="has_separator">False</property>
|
||||||
|
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<widget class="GtkVBox" id="dialog-vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="button2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label">gtk-cancel</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="response_id">-6</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">GTK_PACK_END</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox3">
|
||||||
|
<property name="border_width">6</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkProgressBar" id="progress_bar">
|
||||||
|
<property name="width_request">250</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
|
||||||
|
<property name="fraction">0</property>
|
||||||
|
<property name="pulse_step">0.10000000149</property>
|
||||||
|
<property name="text" translatable="yes">Loading file</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">12</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
</glade-interface>
|
7
debug-viewer/data/gst-debug-viewer.gladep
Normal file
7
debug-viewer/data/gst-debug-viewer.gladep
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||||
|
<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
|
||||||
|
|
||||||
|
<glade-project>
|
||||||
|
<name></name>
|
||||||
|
<program_name></program_name>
|
||||||
|
</glade-project>
|
BIN
debug-viewer/data/gst-debug-viewer.png
Normal file
BIN
debug-viewer/data/gst-debug-viewer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
32
debug-viewer/data/gst-debug-viewer.ui
Normal file
32
debug-viewer/data/gst-debug-viewer.ui
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<!-- -*- mode: xml; -*- -->
|
||||||
|
<ui>
|
||||||
|
<menubar>
|
||||||
|
<menu name="FileMenu" action="FileMenuAction">
|
||||||
|
<menuitem name="FileNewWindow" action="new-window"/>
|
||||||
|
<menuitem name="FileOpen" action="open-file"/>
|
||||||
|
<placeholder name="FileMenuAdditions"/>
|
||||||
|
<separator/>
|
||||||
|
<menuitem name="FileCloseWindow" action="close-window"/>
|
||||||
|
</menu>
|
||||||
|
<menu name="ViewMenu" action="ViewMenuAction">
|
||||||
|
<menu name="ViewColumnsMenu" action="ViewColumnsMenuAction">
|
||||||
|
<menuitem name="ViewColumnsTime" action="show-time-column"/>
|
||||||
|
<menuitem name="ViewColumnsLevel" action="show-level-column"/>
|
||||||
|
<menuitem name="ViewColumnsThread" action="show-thread-column"/>
|
||||||
|
<menuitem name="ViewColumnsCategory" action="show-category-column"/>
|
||||||
|
<menuitem name="ViewColumnsFunction" action="show-function-column"/>
|
||||||
|
<menuitem name="ViewColumnsObject" action="show-object-column"/>
|
||||||
|
<menuitem name="ViewColumnsMessage" action="show-message-column"/>
|
||||||
|
</menu>
|
||||||
|
<placeholder name="ViewMenuAdditions"/>
|
||||||
|
<!--<menuitem name="ViewLineDensity" action="show-line-density"/>-->
|
||||||
|
<separator/>
|
||||||
|
<menuitem name="ViewContextMenuCopyMessage" action="edit-copy-message"/>
|
||||||
|
<menuitem name="ViewContextMenuCopyLine" action="edit-copy-line"/>
|
||||||
|
</menu>
|
||||||
|
<menu name="HelpMenu" action="HelpMenuAction">
|
||||||
|
<placeholder name="HelpMenuAdditions"/>
|
||||||
|
<menuitem name="HelpInfo" action="show-about"/>
|
||||||
|
</menu>
|
||||||
|
</menubar>
|
||||||
|
</ui>
|
9
debug-viewer/gst-debug-viewer.desktop
Normal file
9
debug-viewer/gst-debug-viewer.desktop
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=GStreamer Debug Viewer
|
||||||
|
Comment=Examine GStreamer debug log information
|
||||||
|
StartupNotify=true
|
||||||
|
Exec=python /home/cymacs/src/gst-debug-viewer/gst-debug-viewer.py
|
||||||
|
Icon=/home/cymacs/src/gst-debug-viewer/gst-debug-viewer.png
|
||||||
|
Type=Application
|
||||||
|
Categories=GNOME;Development
|
||||||
|
|
68
debug-viewer/gst-debug-viewer.py
Executable file
68
debug-viewer/gst-debug-viewer.py
Executable file
|
@ -0,0 +1,68 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8; mode: python; -*-
|
||||||
|
#
|
||||||
|
# GStreamer Debug Viewer
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 René Stadler <mail@renestadler.de>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
"""GStreamer Debug Viewer program invocation."""
|
||||||
|
|
||||||
|
def main ():
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
def substituted (s):
|
||||||
|
if s.startswith ("$") and s.endswith ("$"):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
|
||||||
|
# These "$"-enclosed strings are substituted at install time by a custom
|
||||||
|
# distutils extension (see setup.py). If you don't see any dollar signs at
|
||||||
|
# all, you are looking at an installed version of this file.
|
||||||
|
data_dir = substituted ("$DATADIR$")
|
||||||
|
lib_dir = substituted ("$LIBDIR$")
|
||||||
|
|
||||||
|
if data_dir:
|
||||||
|
installed = True
|
||||||
|
else:
|
||||||
|
# Substitution has not been run, we are running uninstalled:
|
||||||
|
lib_dir = os.path.dirname (os.path.abspath (sys.argv[0]))
|
||||||
|
installed = False
|
||||||
|
|
||||||
|
if lib_dir:
|
||||||
|
if not os.path.normpath (lib_dir) in [os.path.normpath (p)
|
||||||
|
for p in sys.path]:
|
||||||
|
sys.path.insert (0, lib_dir)
|
||||||
|
|
||||||
|
try:
|
||||||
|
import GstDebugViewer
|
||||||
|
except ImportError, exc:
|
||||||
|
print >> sys.stderr, str (exc)
|
||||||
|
sys.exit (1)
|
||||||
|
else:
|
||||||
|
if installed:
|
||||||
|
GstDebugViewer.Paths.setup_installed (data_dir)
|
||||||
|
else:
|
||||||
|
# Assume that we reside inside the source dist.
|
||||||
|
source_dir = os.path.dirname (os.path.abspath (sys.argv[0]))
|
||||||
|
GstDebugViewer.Paths.setup_uninstalled (source_dir)
|
||||||
|
|
||||||
|
GstDebugViewer.run ()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main ()
|
BIN
debug-viewer/pixmaps/gst-debug-viewer.png
Normal file
BIN
debug-viewer/pixmaps/gst-debug-viewer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
Loading…
Reference in a new issue