diff --git a/.config/argparse.py b/.config/argparse.py deleted file mode 100644 index 32d948c..0000000 --- a/.config/argparse.py +++ /dev/null @@ -1,2362 +0,0 @@ -# Author: Steven J. Bethard . - -"""Command-line parsing library - -This module is an optparse-inspired command-line parsing library that: - - - handles both optional and positional arguments - - produces highly informative usage messages - - supports parsers that dispatch to sub-parsers - -The following is a simple usage example that sums integers from the -command-line and writes the result to a file:: - - parser = argparse.ArgumentParser( - description='sum the integers at the command line') - parser.add_argument( - 'integers', metavar='int', nargs='+', type=int, - help='an integer to be summed') - parser.add_argument( - '--log', default=sys.stdout, type=argparse.FileType('w'), - help='the file where the sum should be written') - args = parser.parse_args() - args.log.write('%s' % sum(args.integers)) - args.log.close() - -The module contains the following public classes: - - - ArgumentParser -- The main entry point for command-line parsing. As the - example above shows, the add_argument() method is used to populate - the parser with actions for optional and positional arguments. Then - the parse_args() method is invoked to convert the args at the - command-line into an object with attributes. - - - ArgumentError -- The exception raised by ArgumentParser objects when - there are errors with the parser's actions. Errors raised while - parsing the command-line are caught by ArgumentParser and emitted - as command-line messages. - - - FileType -- A factory for defining types of files to be created. As the - example above shows, instances of FileType are typically passed as - the type= argument of add_argument() calls. - - - Action -- The base class for parser actions. Typically actions are - selected by passing strings like 'store_true' or 'append_const' to - the action= argument of add_argument(). However, for greater - customization of ArgumentParser actions, subclasses of Action may - be defined and passed as the action= argument. - - - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter, - ArgumentDefaultsHelpFormatter -- Formatter classes which - may be passed as the formatter_class= argument to the - ArgumentParser constructor. HelpFormatter is the default, - RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser - not to change the formatting for help text, and - ArgumentDefaultsHelpFormatter adds information about argument defaults - to the help. - -All other classes in this module are considered implementation details. -(Also note that HelpFormatter and RawDescriptionHelpFormatter are only -considered public as object names -- the API of the formatter objects is -still considered an implementation detail.) -""" - -__version__ = '1.2.1' -__all__ = [ - 'ArgumentParser', - 'ArgumentError', - 'ArgumentTypeError', - 'FileType', - 'HelpFormatter', - 'ArgumentDefaultsHelpFormatter', - 'RawDescriptionHelpFormatter', - 'RawTextHelpFormatter', - 'Namespace', - 'Action', - 'ONE_OR_MORE', - 'OPTIONAL', - 'PARSER', - 'REMAINDER', - 'SUPPRESS', - 'ZERO_OR_MORE', -] - - -import copy as _copy -import os as _os -import re as _re -import sys as _sys -import textwrap as _textwrap - -from gettext import gettext as _ - -try: - set -except NameError: - # for python < 2.4 compatibility (sets module is there since 2.3): - from sets import Set as set - -try: - basestring -except NameError: - basestring = str - -try: - sorted -except NameError: - # for python < 2.4 compatibility: - def sorted(iterable, reverse=False): - result = list(iterable) - result.sort() - if reverse: - result.reverse() - return result - - -def _callable(obj): - return hasattr(obj, '__call__') or hasattr(obj, '__bases__') - - -SUPPRESS = '==SUPPRESS==' - -OPTIONAL = '?' -ZERO_OR_MORE = '*' -ONE_OR_MORE = '+' -PARSER = 'A...' -REMAINDER = '...' -_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args' - -# ============================= -# Utility functions and classes -# ============================= - -class _AttributeHolder(object): - """Abstract base class that provides __repr__. - - The __repr__ method returns a string in the format:: - ClassName(attr=name, attr=name, ...) - The attributes are determined either by a class-level attribute, - '_kwarg_names', or by inspecting the instance __dict__. - """ - - def __repr__(self): - type_name = type(self).__name__ - arg_strings = [] - for arg in self._get_args(): - arg_strings.append(repr(arg)) - for name, value in self._get_kwargs(): - arg_strings.append('%s=%r' % (name, value)) - return '%s(%s)' % (type_name, ', '.join(arg_strings)) - - def _get_kwargs(self): - return sorted(self.__dict__.items()) - - def _get_args(self): - return [] - - -def _ensure_value(namespace, name, value): - if getattr(namespace, name, None) is None: - setattr(namespace, name, value) - return getattr(namespace, name) - - -# =============== -# Formatting Help -# =============== - -class HelpFormatter(object): - """Formatter for generating usage messages and argument help strings. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def __init__(self, - prog, - indent_increment=2, - max_help_position=24, - width=None): - - # default setting for width - if width is None: - try: - width = int(_os.environ['COLUMNS']) - except (KeyError, ValueError): - width = 80 - width -= 2 - - self._prog = prog - self._indent_increment = indent_increment - self._max_help_position = max_help_position - self._width = width - - self._current_indent = 0 - self._level = 0 - self._action_max_length = 0 - - self._root_section = self._Section(self, None) - self._current_section = self._root_section - - self._whitespace_matcher = _re.compile(r'\s+') - self._long_break_matcher = _re.compile(r'\n\n\n+') - - # =============================== - # Section and indentation methods - # =============================== - def _indent(self): - self._current_indent += self._indent_increment - self._level += 1 - - def _dedent(self): - self._current_indent -= self._indent_increment - assert self._current_indent >= 0, 'Indent decreased below 0.' - self._level -= 1 - - class _Section(object): - - def __init__(self, formatter, parent, heading=None): - self.formatter = formatter - self.parent = parent - self.heading = heading - self.items = [] - - def format_help(self): - # format the indented section - if self.parent is not None: - self.formatter._indent() - join = self.formatter._join_parts - for func, args in self.items: - func(*args) - item_help = join([func(*args) for func, args in self.items]) - if self.parent is not None: - self.formatter._dedent() - - # return nothing if the section was empty - if not item_help: - return '' - - # add the heading if the section was non-empty - if self.heading is not SUPPRESS and self.heading is not None: - current_indent = self.formatter._current_indent - heading = '%*s%s:\n' % (current_indent, '', self.heading) - else: - heading = '' - - # join the section-initial newline, the heading and the help - return join(['\n', heading, item_help, '\n']) - - def _add_item(self, func, args): - self._current_section.items.append((func, args)) - - # ======================== - # Message building methods - # ======================== - def start_section(self, heading): - self._indent() - section = self._Section(self, self._current_section, heading) - self._add_item(section.format_help, []) - self._current_section = section - - def end_section(self): - self._current_section = self._current_section.parent - self._dedent() - - def add_text(self, text): - if text is not SUPPRESS and text is not None: - self._add_item(self._format_text, [text]) - - def add_usage(self, usage, actions, groups, prefix=None): - if usage is not SUPPRESS: - args = usage, actions, groups, prefix - self._add_item(self._format_usage, args) - - def add_argument(self, action): - if action.help is not SUPPRESS: - - # find all invocations - get_invocation = self._format_action_invocation - invocations = [get_invocation(action)] - for subaction in self._iter_indented_subactions(action): - invocations.append(get_invocation(subaction)) - - # update the maximum item length - invocation_length = max([len(s) for s in invocations]) - action_length = invocation_length + self._current_indent - self._action_max_length = max(self._action_max_length, - action_length) - - # add the item to the list - self._add_item(self._format_action, [action]) - - def add_arguments(self, actions): - for action in actions: - self.add_argument(action) - - # ======================= - # Help-formatting methods - # ======================= - def format_help(self): - help = self._root_section.format_help() - if help: - help = self._long_break_matcher.sub('\n\n', help) - help = help.strip('\n') + '\n' - return help - - def _join_parts(self, part_strings): - return ''.join([part - for part in part_strings - if part and part is not SUPPRESS]) - - def _format_usage(self, usage, actions, groups, prefix): - if prefix is None: - prefix = _('usage: ') - - # if usage is specified, use that - if usage is not None: - usage = usage % dict(prog=self._prog) - - # if no optionals or positionals are available, usage is just prog - elif usage is None and not actions: - usage = '%(prog)s' % dict(prog=self._prog) - - # if optionals and positionals are available, calculate usage - elif usage is None: - prog = '%(prog)s' % dict(prog=self._prog) - - # split optionals from positionals - optionals = [] - positionals = [] - for action in actions: - if action.option_strings: - optionals.append(action) - else: - positionals.append(action) - - # build full usage string - format = self._format_actions_usage - action_usage = format(optionals + positionals, groups) - usage = ' '.join([s for s in [prog, action_usage] if s]) - - # wrap the usage parts if it's too long - text_width = self._width - self._current_indent - if len(prefix) + len(usage) > text_width: - - # break usage into wrappable parts - part_regexp = r'\(.*?\)+|\[.*?\]+|\S+' - opt_usage = format(optionals, groups) - pos_usage = format(positionals, groups) - opt_parts = _re.findall(part_regexp, opt_usage) - pos_parts = _re.findall(part_regexp, pos_usage) - assert ' '.join(opt_parts) == opt_usage - assert ' '.join(pos_parts) == pos_usage - - # helper for wrapping lines - def get_lines(parts, indent, prefix=None): - lines = [] - line = [] - if prefix is not None: - line_len = len(prefix) - 1 - else: - line_len = len(indent) - 1 - for part in parts: - if line_len + 1 + len(part) > text_width: - lines.append(indent + ' '.join(line)) - line = [] - line_len = len(indent) - 1 - line.append(part) - line_len += len(part) + 1 - if line: - lines.append(indent + ' '.join(line)) - if prefix is not None: - lines[0] = lines[0][len(indent):] - return lines - - # if prog is short, follow it with optionals or positionals - if len(prefix) + len(prog) <= 0.75 * text_width: - indent = ' ' * (len(prefix) + len(prog) + 1) - if opt_parts: - lines = get_lines([prog] + opt_parts, indent, prefix) - lines.extend(get_lines(pos_parts, indent)) - elif pos_parts: - lines = get_lines([prog] + pos_parts, indent, prefix) - else: - lines = [prog] - - # if prog is long, put it on its own line - else: - indent = ' ' * len(prefix) - parts = opt_parts + pos_parts - lines = get_lines(parts, indent) - if len(lines) > 1: - lines = [] - lines.extend(get_lines(opt_parts, indent)) - lines.extend(get_lines(pos_parts, indent)) - lines = [prog] + lines - - # join lines into usage - usage = '\n'.join(lines) - - # prefix with 'usage:' - return '%s%s\n\n' % (prefix, usage) - - def _format_actions_usage(self, actions, groups): - # find group indices and identify actions in groups - group_actions = set() - inserts = {} - for group in groups: - try: - start = actions.index(group._group_actions[0]) - except ValueError: - continue - else: - end = start + len(group._group_actions) - if actions[start:end] == group._group_actions: - for action in group._group_actions: - group_actions.add(action) - if not group.required: - if start in inserts: - inserts[start] += ' [' - else: - inserts[start] = '[' - inserts[end] = ']' - else: - if start in inserts: - inserts[start] += ' (' - else: - inserts[start] = '(' - inserts[end] = ')' - for i in range(start + 1, end): - inserts[i] = '|' - - # collect all actions format strings - parts = [] - for i, action in enumerate(actions): - - # suppressed arguments are marked with None - # remove | separators for suppressed arguments - if action.help is SUPPRESS: - parts.append(None) - if inserts.get(i) == '|': - inserts.pop(i) - elif inserts.get(i + 1) == '|': - inserts.pop(i + 1) - - # produce all arg strings - elif not action.option_strings: - part = self._format_args(action, action.dest) - - # if it's in a group, strip the outer [] - if action in group_actions: - if part[0] == '[' and part[-1] == ']': - part = part[1:-1] - - # add the action string to the list - parts.append(part) - - # produce the first way to invoke the option in brackets - else: - option_string = action.option_strings[0] - - # if the Optional doesn't take a value, format is: - # -s or --long - if action.nargs == 0: - part = '%s' % option_string - - # if the Optional takes a value, format is: - # -s ARGS or --long ARGS - else: - default = action.dest.upper() - args_string = self._format_args(action, default) - part = '%s %s' % (option_string, args_string) - - # make it look optional if it's not required or in a group - if not action.required and action not in group_actions: - part = '[%s]' % part - - # add the action string to the list - parts.append(part) - - # insert things at the necessary indices - for i in sorted(inserts, reverse=True): - parts[i:i] = [inserts[i]] - - # join all the action items with spaces - text = ' '.join([item for item in parts if item is not None]) - - # clean up separators for mutually exclusive groups - open = r'[\[(]' - close = r'[\])]' - text = _re.sub(r'(%s) ' % open, r'\1', text) - text = _re.sub(r' (%s)' % close, r'\1', text) - text = _re.sub(r'%s *%s' % (open, close), r'', text) - text = _re.sub(r'\(([^|]*)\)', r'\1', text) - text = text.strip() - - # return the text - return text - - def _format_text(self, text): - if '%(prog)' in text: - text = text % dict(prog=self._prog) - text_width = self._width - self._current_indent - indent = ' ' * self._current_indent - return self._fill_text(text, text_width, indent) + '\n\n' - - def _format_action(self, action): - # determine the required width and the entry label - help_position = min(self._action_max_length + 2, - self._max_help_position) - help_width = self._width - help_position - action_width = help_position - self._current_indent - 2 - action_header = self._format_action_invocation(action) - - # ho nelp; start on same line and add a final newline - if not action.help: - tup = self._current_indent, '', action_header - action_header = '%*s%s\n' % tup - - # short action name; start on the same line and pad two spaces - elif len(action_header) <= action_width: - tup = self._current_indent, '', action_width, action_header - action_header = '%*s%-*s ' % tup - indent_first = 0 - - # long action name; start on the next line - else: - tup = self._current_indent, '', action_header - action_header = '%*s%s\n' % tup - indent_first = help_position - - # collect the pieces of the action help - parts = [action_header] - - # if there was help for the action, add lines of help text - if action.help: - help_text = self._expand_help(action) - help_lines = self._split_lines(help_text, help_width) - parts.append('%*s%s\n' % (indent_first, '', help_lines[0])) - for line in help_lines[1:]: - parts.append('%*s%s\n' % (help_position, '', line)) - - # or add a newline if the description doesn't end with one - elif not action_header.endswith('\n'): - parts.append('\n') - - # if there are any sub-actions, add their help as well - for subaction in self._iter_indented_subactions(action): - parts.append(self._format_action(subaction)) - - # return a single string - return self._join_parts(parts) - - def _format_action_invocation(self, action): - if not action.option_strings: - metavar, = self._metavar_formatter(action, action.dest)(1) - return metavar - - else: - parts = [] - - # if the Optional doesn't take a value, format is: - # -s, --long - if action.nargs == 0: - parts.extend(action.option_strings) - - # if the Optional takes a value, format is: - # -s ARGS, --long ARGS - else: - default = action.dest.upper() - args_string = self._format_args(action, default) - for option_string in action.option_strings: - parts.append('%s %s' % (option_string, args_string)) - - return ', '.join(parts) - - def _metavar_formatter(self, action, default_metavar): - if action.metavar is not None: - result = action.metavar - elif action.choices is not None: - choice_strs = [str(choice) for choice in action.choices] - result = '{%s}' % ','.join(choice_strs) - else: - result = default_metavar - - def format(tuple_size): - if isinstance(result, tuple): - return result - else: - return (result, ) * tuple_size - return format - - def _format_args(self, action, default_metavar): - get_metavar = self._metavar_formatter(action, default_metavar) - if action.nargs is None: - result = '%s' % get_metavar(1) - elif action.nargs == OPTIONAL: - result = '[%s]' % get_metavar(1) - elif action.nargs == ZERO_OR_MORE: - result = '[%s [%s ...]]' % get_metavar(2) - elif action.nargs == ONE_OR_MORE: - result = '%s [%s ...]' % get_metavar(2) - elif action.nargs == REMAINDER: - result = '...' - elif action.nargs == PARSER: - result = '%s ...' % get_metavar(1) - else: - formats = ['%s' for _ in range(action.nargs)] - result = ' '.join(formats) % get_metavar(action.nargs) - return result - - def _expand_help(self, action): - params = dict(vars(action), prog=self._prog) - for name in list(params): - if params[name] is SUPPRESS: - del params[name] - for name in list(params): - if hasattr(params[name], '__name__'): - params[name] = params[name].__name__ - if params.get('choices') is not None: - choices_str = ', '.join([str(c) for c in params['choices']]) - params['choices'] = choices_str - return self._get_help_string(action) % params - - def _iter_indented_subactions(self, action): - try: - get_subactions = action._get_subactions - except AttributeError: - pass - else: - self._indent() - for subaction in get_subactions(): - yield subaction - self._dedent() - - def _split_lines(self, text, width): - text = self._whitespace_matcher.sub(' ', text).strip() - return _textwrap.wrap(text, width) - - def _fill_text(self, text, width, indent): - text = self._whitespace_matcher.sub(' ', text).strip() - return _textwrap.fill(text, width, initial_indent=indent, - subsequent_indent=indent) - - def _get_help_string(self, action): - return action.help - - -class RawDescriptionHelpFormatter(HelpFormatter): - """Help message formatter which retains any formatting in descriptions. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def _fill_text(self, text, width, indent): - return ''.join([indent + line for line in text.splitlines(True)]) - - -class RawTextHelpFormatter(RawDescriptionHelpFormatter): - """Help message formatter which retains formatting of all help text. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def _split_lines(self, text, width): - return text.splitlines() - - -class ArgumentDefaultsHelpFormatter(HelpFormatter): - """Help message formatter which adds default values to argument help. - - Only the name of this class is considered a public API. All the methods - provided by the class are considered an implementation detail. - """ - - def _get_help_string(self, action): - help = action.help - if '%(default)' not in action.help: - if action.default is not SUPPRESS: - defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] - if action.option_strings or action.nargs in defaulting_nargs: - help += ' (default: %(default)s)' - return help - - -# ===================== -# Options and Arguments -# ===================== - -def _get_action_name(argument): - if argument is None: - return None - elif argument.option_strings: - return '/'.join(argument.option_strings) - elif argument.metavar not in (None, SUPPRESS): - return argument.metavar - elif argument.dest not in (None, SUPPRESS): - return argument.dest - else: - return None - - -class ArgumentError(Exception): - """An error from creating or using an argument (optional or positional). - - The string value of this exception is the message, augmented with - information about the argument that caused it. - """ - - def __init__(self, argument, message): - self.argument_name = _get_action_name(argument) - self.message = message - - def __str__(self): - if self.argument_name is None: - format = '%(message)s' - else: - format = 'argument %(argument_name)s: %(message)s' - return format % dict(message=self.message, - argument_name=self.argument_name) - - -class ArgumentTypeError(Exception): - """An error from trying to convert a command line string to a type.""" - pass - - -# ============== -# Action classes -# ============== - -class Action(_AttributeHolder): - """Information about how to convert command line strings to Python objects. - - Action objects are used by an ArgumentParser to represent the information - needed to parse a single argument from one or more strings from the - command line. The keyword arguments to the Action constructor are also - all attributes of Action instances. - - Keyword Arguments: - - - option_strings -- A list of command-line option strings which - should be associated with this action. - - - dest -- The name of the attribute to hold the created object(s) - - - nargs -- The number of command-line arguments that should be - consumed. By default, one argument will be consumed and a single - value will be produced. Other values include: - - N (an integer) consumes N arguments (and produces a list) - - '?' consumes zero or one arguments - - '*' consumes zero or more arguments (and produces a list) - - '+' consumes one or more arguments (and produces a list) - Note that the difference between the default and nargs=1 is that - with the default, a single value will be produced, while with - nargs=1, a list containing a single value will be produced. - - - const -- The value to be produced if the option is specified and the - option uses an action that takes no values. - - - default -- The value to be produced if the option is not specified. - - - type -- The type which the command-line arguments should be converted - to, should be one of 'string', 'int', 'float', 'complex' or a - callable object that accepts a single string argument. If None, - 'string' is assumed. - - - choices -- A container of values that should be allowed. If not None, - after a command-line argument has been converted to the appropriate - type, an exception will be raised if it is not a member of this - collection. - - - required -- True if the action must always be specified at the - command line. This is only meaningful for optional command-line - arguments. - - - help -- The help string describing the argument. - - - metavar -- The name to be used for the option's argument with the - help string. If None, the 'dest' value will be used as the name. - """ - - def __init__(self, - option_strings, - dest, - nargs=None, - const=None, - default=None, - type=None, - choices=None, - required=False, - help=None, - metavar=None): - self.option_strings = option_strings - self.dest = dest - self.nargs = nargs - self.const = const - self.default = default - self.type = type - self.choices = choices - self.required = required - self.help = help - self.metavar = metavar - - def _get_kwargs(self): - names = [ - 'option_strings', - 'dest', - 'nargs', - 'const', - 'default', - 'type', - 'choices', - 'help', - 'metavar', - ] - return [(name, getattr(self, name)) for name in names] - - def __call__(self, parser, namespace, values, option_string=None): - raise NotImplementedError(_('.__call__() not defined')) - - -class _StoreAction(Action): - - def __init__(self, - option_strings, - dest, - nargs=None, - const=None, - default=None, - type=None, - choices=None, - required=False, - help=None, - metavar=None): - if nargs == 0: - raise ValueError('nargs for store actions must be > 0; if you ' - 'have nothing to store, actions such as store ' - 'true or store const may be more appropriate') - if const is not None and nargs != OPTIONAL: - raise ValueError('nargs must be %r to supply const' % OPTIONAL) - super(_StoreAction, self).__init__( - option_strings=option_strings, - dest=dest, - nargs=nargs, - const=const, - default=default, - type=type, - choices=choices, - required=required, - help=help, - metavar=metavar) - - def __call__(self, parser, namespace, values, option_string=None): - setattr(namespace, self.dest, values) - - -class _StoreConstAction(Action): - - def __init__(self, - option_strings, - dest, - const, - default=None, - required=False, - help=None, - metavar=None): - super(_StoreConstAction, self).__init__( - option_strings=option_strings, - dest=dest, - nargs=0, - const=const, - default=default, - required=required, - help=help) - - def __call__(self, parser, namespace, values, option_string=None): - setattr(namespace, self.dest, self.const) - - -class _StoreTrueAction(_StoreConstAction): - - def __init__(self, - option_strings, - dest, - default=False, - required=False, - help=None): - super(_StoreTrueAction, self).__init__( - option_strings=option_strings, - dest=dest, - const=True, - default=default, - required=required, - help=help) - - -class _StoreFalseAction(_StoreConstAction): - - def __init__(self, - option_strings, - dest, - default=True, - required=False, - help=None): - super(_StoreFalseAction, self).__init__( - option_strings=option_strings, - dest=dest, - const=False, - default=default, - required=required, - help=help) - - -class _AppendAction(Action): - - def __init__(self, - option_strings, - dest, - nargs=None, - const=None, - default=None, - type=None, - choices=None, - required=False, - help=None, - metavar=None): - if nargs == 0: - raise ValueError('nargs for append actions must be > 0; if arg ' - 'strings are not supplying the value to append, ' - 'the append const action may be more appropriate') - if const is not None and nargs != OPTIONAL: - raise ValueError('nargs must be %r to supply const' % OPTIONAL) - super(_AppendAction, self).__init__( - option_strings=option_strings, - dest=dest, - nargs=nargs, - const=const, - default=default, - type=type, - choices=choices, - required=required, - help=help, - metavar=metavar) - - def __call__(self, parser, namespace, values, option_string=None): - items = _copy.copy(_ensure_value(namespace, self.dest, [])) - items.append(values) - setattr(namespace, self.dest, items) - - -class _AppendConstAction(Action): - - def __init__(self, - option_strings, - dest, - const, - default=None, - required=False, - help=None, - metavar=None): - super(_AppendConstAction, self).__init__( - option_strings=option_strings, - dest=dest, - nargs=0, - const=const, - default=default, - required=required, - help=help, - metavar=metavar) - - def __call__(self, parser, namespace, values, option_string=None): - items = _copy.copy(_ensure_value(namespace, self.dest, [])) - items.append(self.const) - setattr(namespace, self.dest, items) - - -class _CountAction(Action): - - def __init__(self, - option_strings, - dest, - default=None, - required=False, - help=None): - super(_CountAction, self).__init__( - option_strings=option_strings, - dest=dest, - nargs=0, - default=default, - required=required, - help=help) - - def __call__(self, parser, namespace, values, option_string=None): - new_count = _ensure_value(namespace, self.dest, 0) + 1 - setattr(namespace, self.dest, new_count) - - -class _HelpAction(Action): - - def __init__(self, - option_strings, - dest=SUPPRESS, - default=SUPPRESS, - help=None): - super(_HelpAction, self).__init__( - option_strings=option_strings, - dest=dest, - default=default, - nargs=0, - help=help) - - def __call__(self, parser, namespace, values, option_string=None): - parser.print_help() - parser.exit() - - -class _VersionAction(Action): - - def __init__(self, - option_strings, - version=None, - dest=SUPPRESS, - default=SUPPRESS, - help="show program's version number and exit"): - super(_VersionAction, self).__init__( - option_strings=option_strings, - dest=dest, - default=default, - nargs=0, - help=help) - self.version = version - - def __call__(self, parser, namespace, values, option_string=None): - version = self.version - if version is None: - version = parser.version - formatter = parser._get_formatter() - formatter.add_text(version) - parser.exit(message=formatter.format_help()) - - -class _SubParsersAction(Action): - - class _ChoicesPseudoAction(Action): - - def __init__(self, name, help): - sup = super(_SubParsersAction._ChoicesPseudoAction, self) - sup.__init__(option_strings=[], dest=name, help=help) - - def __init__(self, - option_strings, - prog, - parser_class, - dest=SUPPRESS, - help=None, - metavar=None): - - self._prog_prefix = prog - self._parser_class = parser_class - self._name_parser_map = {} - self._choices_actions = [] - - super(_SubParsersAction, self).__init__( - option_strings=option_strings, - dest=dest, - nargs=PARSER, - choices=self._name_parser_map, - help=help, - metavar=metavar) - - def add_parser(self, name, **kwargs): - # set prog from the existing prefix - if kwargs.get('prog') is None: - kwargs['prog'] = '%s %s' % (self._prog_prefix, name) - - # create a pseudo-action to hold the choice help - if 'help' in kwargs: - help = kwargs.pop('help') - choice_action = self._ChoicesPseudoAction(name, help) - self._choices_actions.append(choice_action) - - # create the parser and add it to the map - parser = self._parser_class(**kwargs) - self._name_parser_map[name] = parser - return parser - - def _get_subactions(self): - return self._choices_actions - - def __call__(self, parser, namespace, values, option_string=None): - parser_name = values[0] - arg_strings = values[1:] - - # set the parser name if requested - if self.dest is not SUPPRESS: - setattr(namespace, self.dest, parser_name) - - # select the parser - try: - parser = self._name_parser_map[parser_name] - except KeyError: - tup = parser_name, ', '.join(self._name_parser_map) - msg = _('unknown parser %r (choices: %s)' % tup) - raise ArgumentError(self, msg) - - # parse all the remaining options into the namespace - # store any unrecognized options on the object, so that the top - # level parser can decide what to do with them - namespace, arg_strings = parser.parse_known_args(arg_strings, namespace) - if arg_strings: - vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) - getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) - - -# ============== -# Type classes -# ============== - -class FileType(object): - """Factory for creating file object types - - Instances of FileType are typically passed as type= arguments to the - ArgumentParser add_argument() method. - - Keyword Arguments: - - mode -- A string indicating how the file is to be opened. Accepts the - same values as the builtin open() function. - - bufsize -- The file's desired buffer size. Accepts the same values as - the builtin open() function. - """ - - def __init__(self, mode='r', bufsize=None): - self._mode = mode - self._bufsize = bufsize - - def __call__(self, string): - # the special argument "-" means sys.std{in,out} - if string == '-': - if 'r' in self._mode: - return _sys.stdin - elif 'w' in self._mode: - return _sys.stdout - else: - msg = _('argument "-" with mode %r' % self._mode) - raise ValueError(msg) - - # all other arguments are used as file names - if self._bufsize: - return open(string, self._mode, self._bufsize) - else: - return open(string, self._mode) - - def __repr__(self): - args = [self._mode, self._bufsize] - args_str = ', '.join([repr(arg) for arg in args if arg is not None]) - return '%s(%s)' % (type(self).__name__, args_str) - -# =========================== -# Optional and Positional Parsing -# =========================== - -class Namespace(_AttributeHolder): - """Simple object for storing attributes. - - Implements equality by attribute names and values, and provides a simple - string representation. - """ - - def __init__(self, **kwargs): - for name in kwargs: - setattr(self, name, kwargs[name]) - - __hash__ = None - - def __eq__(self, other): - return vars(self) == vars(other) - - def __ne__(self, other): - return not (self == other) - - def __contains__(self, key): - return key in self.__dict__ - - -class _ActionsContainer(object): - - def __init__(self, - description, - prefix_chars, - argument_default, - conflict_handler): - super(_ActionsContainer, self).__init__() - - self.description = description - self.argument_default = argument_default - self.prefix_chars = prefix_chars - self.conflict_handler = conflict_handler - - # set up registries - self._registries = {} - - # register actions - self.register('action', None, _StoreAction) - self.register('action', 'store', _StoreAction) - self.register('action', 'store_const', _StoreConstAction) - self.register('action', 'store_true', _StoreTrueAction) - self.register('action', 'store_false', _StoreFalseAction) - self.register('action', 'append', _AppendAction) - self.register('action', 'append_const', _AppendConstAction) - self.register('action', 'count', _CountAction) - self.register('action', 'help', _HelpAction) - self.register('action', 'version', _VersionAction) - self.register('action', 'parsers', _SubParsersAction) - - # raise an exception if the conflict handler is invalid - self._get_handler() - - # action storage - self._actions = [] - self._option_string_actions = {} - - # groups - self._action_groups = [] - self._mutually_exclusive_groups = [] - - # defaults storage - self._defaults = {} - - # determines whether an "option" looks like a negative number - self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$') - - # whether or not there are any optionals that look like negative - # numbers -- uses a list so it can be shared and edited - self._has_negative_number_optionals = [] - - # ==================== - # Registration methods - # ==================== - def register(self, registry_name, value, object): - registry = self._registries.setdefault(registry_name, {}) - registry[value] = object - - def _registry_get(self, registry_name, value, default=None): - return self._registries[registry_name].get(value, default) - - # ================================== - # Namespace default accessor methods - # ================================== - def set_defaults(self, **kwargs): - self._defaults.update(kwargs) - - # if these defaults match any existing arguments, replace - # the previous default on the object with the new one - for action in self._actions: - if action.dest in kwargs: - action.default = kwargs[action.dest] - - def get_default(self, dest): - for action in self._actions: - if action.dest == dest and action.default is not None: - return action.default - return self._defaults.get(dest, None) - - - # ======================= - # Adding argument actions - # ======================= - def add_argument(self, *args, **kwargs): - """ - add_argument(dest, ..., name=value, ...) - add_argument(option_string, option_string, ..., name=value, ...) - """ - - # if no positional args are supplied or only one is supplied and - # it doesn't look like an option string, parse a positional - # argument - chars = self.prefix_chars - if not args or len(args) == 1 and args[0][0] not in chars: - if args and 'dest' in kwargs: - raise ValueError('dest supplied twice for positional argument') - kwargs = self._get_positional_kwargs(*args, **kwargs) - - # otherwise, we're adding an optional argument - else: - kwargs = self._get_optional_kwargs(*args, **kwargs) - - # if no default was supplied, use the parser-level default - if 'default' not in kwargs: - dest = kwargs['dest'] - if dest in self._defaults: - kwargs['default'] = self._defaults[dest] - elif self.argument_default is not None: - kwargs['default'] = self.argument_default - - # create the action object, and add it to the parser - action_class = self._pop_action_class(kwargs) - if not _callable(action_class): - raise ValueError('unknown action "%s"' % action_class) - action = action_class(**kwargs) - - # raise an error if the action type is not callable - type_func = self._registry_get('type', action.type, action.type) - if not _callable(type_func): - raise ValueError('%r is not callable' % type_func) - - return self._add_action(action) - - def add_argument_group(self, *args, **kwargs): - group = _ArgumentGroup(self, *args, **kwargs) - self._action_groups.append(group) - return group - - def add_mutually_exclusive_group(self, **kwargs): - group = _MutuallyExclusiveGroup(self, **kwargs) - self._mutually_exclusive_groups.append(group) - return group - - def _add_action(self, action): - # resolve any conflicts - self._check_conflict(action) - - # add to actions list - self._actions.append(action) - action.container = self - - # index the action by any option strings it has - for option_string in action.option_strings: - self._option_string_actions[option_string] = action - - # set the flag if any option strings look like negative numbers - for option_string in action.option_strings: - if self._negative_number_matcher.match(option_string): - if not self._has_negative_number_optionals: - self._has_negative_number_optionals.append(True) - - # return the created action - return action - - def _remove_action(self, action): - self._actions.remove(action) - - def _add_container_actions(self, container): - # collect groups by titles - title_group_map = {} - for group in self._action_groups: - if group.title in title_group_map: - msg = _('cannot merge actions - two groups are named %r') - raise ValueError(msg % (group.title)) - title_group_map[group.title] = group - - # map each action to its group - group_map = {} - for group in container._action_groups: - - # if a group with the title exists, use that, otherwise - # create a new group matching the container's group - if group.title not in title_group_map: - title_group_map[group.title] = self.add_argument_group( - title=group.title, - description=group.description, - conflict_handler=group.conflict_handler) - - # map the actions to their new group - for action in group._group_actions: - group_map[action] = title_group_map[group.title] - - # add container's mutually exclusive groups - # NOTE: if add_mutually_exclusive_group ever gains title= and - # description= then this code will need to be expanded as above - for group in container._mutually_exclusive_groups: - mutex_group = self.add_mutually_exclusive_group( - required=group.required) - - # map the actions to their new mutex group - for action in group._group_actions: - group_map[action] = mutex_group - - # add all actions to this container or their group - for action in container._actions: - group_map.get(action, self)._add_action(action) - - def _get_positional_kwargs(self, dest, **kwargs): - # make sure required is not specified - if 'required' in kwargs: - msg = _("'required' is an invalid argument for positionals") - raise TypeError(msg) - - # mark positional arguments as required if at least one is - # always required - if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]: - kwargs['required'] = True - if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs: - kwargs['required'] = True - - # return the keyword arguments with no option strings - return dict(kwargs, dest=dest, option_strings=[]) - - def _get_optional_kwargs(self, *args, **kwargs): - # determine short and long option strings - option_strings = [] - long_option_strings = [] - for option_string in args: - # error on strings that don't start with an appropriate prefix - if not option_string[0] in self.prefix_chars: - msg = _('invalid option string %r: ' - 'must start with a character %r') - tup = option_string, self.prefix_chars - raise ValueError(msg % tup) - - # strings starting with two prefix characters are long options - option_strings.append(option_string) - if option_string[0] in self.prefix_chars: - if len(option_string) > 1: - if option_string[1] in self.prefix_chars: - long_option_strings.append(option_string) - - # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' - dest = kwargs.pop('dest', None) - if dest is None: - if long_option_strings: - dest_option_string = long_option_strings[0] - else: - dest_option_string = option_strings[0] - dest = dest_option_string.lstrip(self.prefix_chars) - if not dest: - msg = _('dest= is required for options like %r') - raise ValueError(msg % option_string) - dest = dest.replace('-', '_') - - # return the updated keyword arguments - return dict(kwargs, dest=dest, option_strings=option_strings) - - def _pop_action_class(self, kwargs, default=None): - action = kwargs.pop('action', default) - return self._registry_get('action', action, action) - - def _get_handler(self): - # determine function from conflict handler string - handler_func_name = '_handle_conflict_%s' % self.conflict_handler - try: - return getattr(self, handler_func_name) - except AttributeError: - msg = _('invalid conflict_resolution value: %r') - raise ValueError(msg % self.conflict_handler) - - def _check_conflict(self, action): - - # find all options that conflict with this option - confl_optionals = [] - for option_string in action.option_strings: - if option_string in self._option_string_actions: - confl_optional = self._option_string_actions[option_string] - confl_optionals.append((option_string, confl_optional)) - - # resolve any conflicts - if confl_optionals: - conflict_handler = self._get_handler() - conflict_handler(action, confl_optionals) - - def _handle_conflict_error(self, action, conflicting_actions): - message = _('conflicting option string(s): %s') - conflict_string = ', '.join([option_string - for option_string, action - in conflicting_actions]) - raise ArgumentError(action, message % conflict_string) - - def _handle_conflict_resolve(self, action, conflicting_actions): - - # remove all conflicting options - for option_string, action in conflicting_actions: - - # remove the conflicting option - action.option_strings.remove(option_string) - self._option_string_actions.pop(option_string, None) - - # if the option now has no option string, remove it from the - # container holding it - if not action.option_strings: - action.container._remove_action(action) - - -class _ArgumentGroup(_ActionsContainer): - - def __init__(self, container, title=None, description=None, **kwargs): - # add any missing keyword arguments by checking the container - update = kwargs.setdefault - update('conflict_handler', container.conflict_handler) - update('prefix_chars', container.prefix_chars) - update('argument_default', container.argument_default) - super_init = super(_ArgumentGroup, self).__init__ - super_init(description=description, **kwargs) - - # group attributes - self.title = title - self._group_actions = [] - - # share most attributes with the container - self._registries = container._registries - self._actions = container._actions - self._option_string_actions = container._option_string_actions - self._defaults = container._defaults - self._has_negative_number_optionals = \ - container._has_negative_number_optionals - - def _add_action(self, action): - action = super(_ArgumentGroup, self)._add_action(action) - self._group_actions.append(action) - return action - - def _remove_action(self, action): - super(_ArgumentGroup, self)._remove_action(action) - self._group_actions.remove(action) - - -class _MutuallyExclusiveGroup(_ArgumentGroup): - - def __init__(self, container, required=False): - super(_MutuallyExclusiveGroup, self).__init__(container) - self.required = required - self._container = container - - def _add_action(self, action): - if action.required: - msg = _('mutually exclusive arguments must be optional') - raise ValueError(msg) - action = self._container._add_action(action) - self._group_actions.append(action) - return action - - def _remove_action(self, action): - self._container._remove_action(action) - self._group_actions.remove(action) - - -class ArgumentParser(_AttributeHolder, _ActionsContainer): - """Object for parsing command line strings into Python objects. - - Keyword Arguments: - - prog -- The name of the program (default: sys.argv[0]) - - usage -- A usage message (default: auto-generated from arguments) - - description -- A description of what the program does - - epilog -- Text following the argument descriptions - - parents -- Parsers whose arguments should be copied into this one - - formatter_class -- HelpFormatter class for printing help messages - - prefix_chars -- Characters that prefix optional arguments - - fromfile_prefix_chars -- Characters that prefix files containing - additional arguments - - argument_default -- The default value for all arguments - - conflict_handler -- String indicating how to handle conflicts - - add_help -- Add a -h/-help option - """ - - def __init__(self, - prog=None, - usage=None, - description=None, - epilog=None, - version=None, - parents=[], - formatter_class=HelpFormatter, - prefix_chars='-', - fromfile_prefix_chars=None, - argument_default=None, - conflict_handler='error', - add_help=True): - - if version is not None: - import warnings - warnings.warn( - """The "version" argument to ArgumentParser is deprecated. """ - """Please use """ - """"add_argument(..., action='version', version="N", ...)" """ - """instead""", DeprecationWarning) - - superinit = super(ArgumentParser, self).__init__ - superinit(description=description, - prefix_chars=prefix_chars, - argument_default=argument_default, - conflict_handler=conflict_handler) - - # default setting for prog - if prog is None: - prog = _os.path.basename(_sys.argv[0]) - - self.prog = prog - self.usage = usage - self.epilog = epilog - self.version = version - self.formatter_class = formatter_class - self.fromfile_prefix_chars = fromfile_prefix_chars - self.add_help = add_help - - add_group = self.add_argument_group - self._positionals = add_group(_('positional arguments')) - self._optionals = add_group(_('optional arguments')) - self._subparsers = None - - # register types - def identity(string): - return string - self.register('type', None, identity) - - # add help and version arguments if necessary - # (using explicit default to override global argument_default) - if '-' in prefix_chars: - default_prefix = '-' - else: - default_prefix = prefix_chars[0] - if self.add_help: - self.add_argument( - default_prefix+'h', default_prefix*2+'help', - action='help', default=SUPPRESS, - help=_('show this help message and exit')) - if self.version: - self.add_argument( - default_prefix+'v', default_prefix*2+'version', - action='version', default=SUPPRESS, - version=self.version, - help=_("show program's version number and exit")) - - # add parent arguments and defaults - for parent in parents: - self._add_container_actions(parent) - try: - defaults = parent._defaults - except AttributeError: - pass - else: - self._defaults.update(defaults) - - # ======================= - # Pretty __repr__ methods - # ======================= - def _get_kwargs(self): - names = [ - 'prog', - 'usage', - 'description', - 'version', - 'formatter_class', - 'conflict_handler', - 'add_help', - ] - return [(name, getattr(self, name)) for name in names] - - # ================================== - # Optional/Positional adding methods - # ================================== - def add_subparsers(self, **kwargs): - if self._subparsers is not None: - self.error(_('cannot have multiple subparser arguments')) - - # add the parser class to the arguments if it's not present - kwargs.setdefault('parser_class', type(self)) - - if 'title' in kwargs or 'description' in kwargs: - title = _(kwargs.pop('title', 'subcommands')) - description = _(kwargs.pop('description', None)) - self._subparsers = self.add_argument_group(title, description) - else: - self._subparsers = self._positionals - - # prog defaults to the usage message of this parser, skipping - # optional arguments and with no "usage:" prefix - if kwargs.get('prog') is None: - formatter = self._get_formatter() - positionals = self._get_positional_actions() - groups = self._mutually_exclusive_groups - formatter.add_usage(self.usage, positionals, groups, '') - kwargs['prog'] = formatter.format_help().strip() - - # create the parsers action and add it to the positionals list - parsers_class = self._pop_action_class(kwargs, 'parsers') - action = parsers_class(option_strings=[], **kwargs) - self._subparsers._add_action(action) - - # return the created parsers action - return action - - def _add_action(self, action): - if action.option_strings: - self._optionals._add_action(action) - else: - self._positionals._add_action(action) - return action - - def _get_optional_actions(self): - return [action - for action in self._actions - if action.option_strings] - - def _get_positional_actions(self): - return [action - for action in self._actions - if not action.option_strings] - - # ===================================== - # Command line argument parsing methods - # ===================================== - def parse_args(self, args=None, namespace=None): - args, argv = self.parse_known_args(args, namespace) - if argv: - msg = _('unrecognized arguments: %s') - self.error(msg % ' '.join(argv)) - return args - - def parse_known_args(self, args=None, namespace=None): - # args default to the system args - if args is None: - args = _sys.argv[1:] - - # default Namespace built from parser defaults - if namespace is None: - namespace = Namespace() - - # add any action defaults that aren't present - for action in self._actions: - if action.dest is not SUPPRESS: - if not hasattr(namespace, action.dest): - if action.default is not SUPPRESS: - default = action.default - if isinstance(action.default, basestring): - default = self._get_value(action, default) - setattr(namespace, action.dest, default) - - # add any parser defaults that aren't present - for dest in self._defaults: - if not hasattr(namespace, dest): - setattr(namespace, dest, self._defaults[dest]) - - # parse the arguments and exit if there are any errors - try: - namespace, args = self._parse_known_args(args, namespace) - if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): - args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) - delattr(namespace, _UNRECOGNIZED_ARGS_ATTR) - return namespace, args - except ArgumentError: - err = _sys.exc_info()[1] - self.error(str(err)) - - def _parse_known_args(self, arg_strings, namespace): - # replace arg strings that are file references - if self.fromfile_prefix_chars is not None: - arg_strings = self._read_args_from_files(arg_strings) - - # map all mutually exclusive arguments to the other arguments - # they can't occur with - action_conflicts = {} - for mutex_group in self._mutually_exclusive_groups: - group_actions = mutex_group._group_actions - for i, mutex_action in enumerate(mutex_group._group_actions): - conflicts = action_conflicts.setdefault(mutex_action, []) - conflicts.extend(group_actions[:i]) - conflicts.extend(group_actions[i + 1:]) - - # find all option indices, and determine the arg_string_pattern - # which has an 'O' if there is an option at an index, - # an 'A' if there is an argument, or a '-' if there is a '--' - option_string_indices = {} - arg_string_pattern_parts = [] - arg_strings_iter = iter(arg_strings) - for i, arg_string in enumerate(arg_strings_iter): - - # all args after -- are non-options - if arg_string == '--': - arg_string_pattern_parts.append('-') - for arg_string in arg_strings_iter: - arg_string_pattern_parts.append('A') - - # otherwise, add the arg to the arg strings - # and note the index if it was an option - else: - option_tuple = self._parse_optional(arg_string) - if option_tuple is None: - pattern = 'A' - else: - option_string_indices[i] = option_tuple - pattern = 'O' - arg_string_pattern_parts.append(pattern) - - # join the pieces together to form the pattern - arg_strings_pattern = ''.join(arg_string_pattern_parts) - - # converts arg strings to the appropriate and then takes the action - seen_actions = set() - seen_non_default_actions = set() - - def take_action(action, argument_strings, option_string=None): - seen_actions.add(action) - argument_values = self._get_values(action, argument_strings) - - # error if this argument is not allowed with other previously - # seen arguments, assuming that actions that use the default - # value don't really count as "present" - if argument_values is not action.default: - seen_non_default_actions.add(action) - for conflict_action in action_conflicts.get(action, []): - if conflict_action in seen_non_default_actions: - msg = _('not allowed with argument %s') - action_name = _get_action_name(conflict_action) - raise ArgumentError(action, msg % action_name) - - # take the action if we didn't receive a SUPPRESS value - # (e.g. from a default) - if argument_values is not SUPPRESS: - action(self, namespace, argument_values, option_string) - - # function to convert arg_strings into an optional action - def consume_optional(start_index): - - # get the optional identified at this index - option_tuple = option_string_indices[start_index] - action, option_string, explicit_arg = option_tuple - - # identify additional optionals in the same arg string - # (e.g. -xyz is the same as -x -y -z if no args are required) - match_argument = self._match_argument - action_tuples = [] - while True: - - # if we found no optional action, skip it - if action is None: - extras.append(arg_strings[start_index]) - return start_index + 1 - - # if there is an explicit argument, try to match the - # optional's string arguments to only this - if explicit_arg is not None: - arg_count = match_argument(action, 'A') - - # if the action is a single-dash option and takes no - # arguments, try to parse more single-dash options out - # of the tail of the option string - chars = self.prefix_chars - if arg_count == 0 and option_string[1] not in chars: - action_tuples.append((action, [], option_string)) - char = option_string[0] - option_string = char + explicit_arg[0] - new_explicit_arg = explicit_arg[1:] or None - optionals_map = self._option_string_actions - if option_string in optionals_map: - action = optionals_map[option_string] - explicit_arg = new_explicit_arg - else: - msg = _('ignored explicit argument %r') - raise ArgumentError(action, msg % explicit_arg) - - # if the action expect exactly one argument, we've - # successfully matched the option; exit the loop - elif arg_count == 1: - stop = start_index + 1 - args = [explicit_arg] - action_tuples.append((action, args, option_string)) - break - - # error if a double-dash option did not use the - # explicit argument - else: - msg = _('ignored explicit argument %r') - raise ArgumentError(action, msg % explicit_arg) - - # if there is no explicit argument, try to match the - # optional's string arguments with the following strings - # if successful, exit the loop - else: - start = start_index + 1 - selected_patterns = arg_strings_pattern[start:] - arg_count = match_argument(action, selected_patterns) - stop = start + arg_count - args = arg_strings[start:stop] - action_tuples.append((action, args, option_string)) - break - - # add the Optional to the list and return the index at which - # the Optional's string args stopped - assert action_tuples - for action, args, option_string in action_tuples: - take_action(action, args, option_string) - return stop - - # the list of Positionals left to be parsed; this is modified - # by consume_positionals() - positionals = self._get_positional_actions() - - # function to convert arg_strings into positional actions - def consume_positionals(start_index): - # match as many Positionals as possible - match_partial = self._match_arguments_partial - selected_pattern = arg_strings_pattern[start_index:] - arg_counts = match_partial(positionals, selected_pattern) - - # slice off the appropriate arg strings for each Positional - # and add the Positional and its args to the list - for action, arg_count in zip(positionals, arg_counts): - args = arg_strings[start_index: start_index + arg_count] - start_index += arg_count - take_action(action, args) - - # slice off the Positionals that we just parsed and return the - # index at which the Positionals' string args stopped - positionals[:] = positionals[len(arg_counts):] - return start_index - - # consume Positionals and Optionals alternately, until we have - # passed the last option string - extras = [] - start_index = 0 - if option_string_indices: - max_option_string_index = max(option_string_indices) - else: - max_option_string_index = -1 - while start_index <= max_option_string_index: - - # consume any Positionals preceding the next option - next_option_string_index = min([ - index - for index in option_string_indices - if index >= start_index]) - if start_index != next_option_string_index: - positionals_end_index = consume_positionals(start_index) - - # only try to parse the next optional if we didn't consume - # the option string during the positionals parsing - if positionals_end_index > start_index: - start_index = positionals_end_index - continue - else: - start_index = positionals_end_index - - # if we consumed all the positionals we could and we're not - # at the index of an option string, there were extra arguments - if start_index not in option_string_indices: - strings = arg_strings[start_index:next_option_string_index] - extras.extend(strings) - start_index = next_option_string_index - - # consume the next optional and any arguments for it - start_index = consume_optional(start_index) - - # consume any positionals following the last Optional - stop_index = consume_positionals(start_index) - - # if we didn't consume all the argument strings, there were extras - extras.extend(arg_strings[stop_index:]) - - # if we didn't use all the Positional objects, there were too few - # arg strings supplied. - if positionals: - self.error(_('too few arguments')) - - # make sure all required actions were present - for action in self._actions: - if action.required: - if action not in seen_actions: - name = _get_action_name(action) - self.error(_('argument %s is required') % name) - - # make sure all required groups had one option present - for group in self._mutually_exclusive_groups: - if group.required: - for action in group._group_actions: - if action in seen_non_default_actions: - break - - # if no actions were used, report the error - else: - names = [_get_action_name(action) - for action in group._group_actions - if action.help is not SUPPRESS] - msg = _('one of the arguments %s is required') - self.error(msg % ' '.join(names)) - - # return the updated namespace and the extra arguments - return namespace, extras - - def _read_args_from_files(self, arg_strings): - # expand arguments referencing files - new_arg_strings = [] - for arg_string in arg_strings: - - # for regular arguments, just add them back into the list - if arg_string[0] not in self.fromfile_prefix_chars: - new_arg_strings.append(arg_string) - - # replace arguments referencing files with the file content - else: - try: - args_file = open(arg_string[1:]) - try: - arg_strings = [] - for arg_line in args_file.read().splitlines(): - for arg in self.convert_arg_line_to_args(arg_line): - arg_strings.append(arg) - arg_strings = self._read_args_from_files(arg_strings) - new_arg_strings.extend(arg_strings) - finally: - args_file.close() - except IOError: - err = _sys.exc_info()[1] - self.error(str(err)) - - # return the modified argument list - return new_arg_strings - - def convert_arg_line_to_args(self, arg_line): - return [arg_line] - - def _match_argument(self, action, arg_strings_pattern): - # match the pattern for this action to the arg strings - nargs_pattern = self._get_nargs_pattern(action) - match = _re.match(nargs_pattern, arg_strings_pattern) - - # raise an exception if we weren't able to find a match - if match is None: - nargs_errors = { - None: _('expected one argument'), - OPTIONAL: _('expected at most one argument'), - ONE_OR_MORE: _('expected at least one argument'), - } - default = _('expected %s argument(s)') % action.nargs - msg = nargs_errors.get(action.nargs, default) - raise ArgumentError(action, msg) - - # return the number of arguments matched - return len(match.group(1)) - - def _match_arguments_partial(self, actions, arg_strings_pattern): - # progressively shorten the actions list by slicing off the - # final actions until we find a match - result = [] - for i in range(len(actions), 0, -1): - actions_slice = actions[:i] - pattern = ''.join([self._get_nargs_pattern(action) - for action in actions_slice]) - match = _re.match(pattern, arg_strings_pattern) - if match is not None: - result.extend([len(string) for string in match.groups()]) - break - - # return the list of arg string counts - return result - - def _parse_optional(self, arg_string): - # if it's an empty string, it was meant to be a positional - if not arg_string: - return None - - # if it doesn't start with a prefix, it was meant to be positional - if not arg_string[0] in self.prefix_chars: - return None - - # if the option string is present in the parser, return the action - if arg_string in self._option_string_actions: - action = self._option_string_actions[arg_string] - return action, arg_string, None - - # if it's just a single character, it was meant to be positional - if len(arg_string) == 1: - return None - - # if the option string before the "=" is present, return the action - if '=' in arg_string: - option_string, explicit_arg = arg_string.split('=', 1) - if option_string in self._option_string_actions: - action = self._option_string_actions[option_string] - return action, option_string, explicit_arg - - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples = self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options = ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - tup = arg_string, options - self.error(_('ambiguous option: %s could match %s') % tup) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) == 1: - option_tuple, = option_tuples - return option_tuple - - # if it was not found as an option, but it looks like a negative - # number, it was meant to be positional - # unless there are negative-number-like options - if self._negative_number_matcher.match(arg_string): - if not self._has_negative_number_optionals: - return None - - # if it contains a space, it was meant to be a positional - if ' ' in arg_string: - return None - - # it was meant to be an optional but there is no such option - # in this parser (though it might be a valid option in a subparser) - return None, arg_string, None - - def _get_option_tuples(self, option_string): - result = [] - - # option strings starting with two prefix characters are only - # split at the '=' - chars = self.prefix_chars - if option_string[0] in chars and option_string[1] in chars: - if '=' in option_string: - option_prefix, explicit_arg = option_string.split('=', 1) - else: - option_prefix = option_string - explicit_arg = None - for option_string in self._option_string_actions: - if option_string.startswith(option_prefix): - action = self._option_string_actions[option_string] - tup = action, option_string, explicit_arg - result.append(tup) - - # single character options can be concatenated with their arguments - # but multiple character options always have to have their argument - # separate - elif option_string[0] in chars and option_string[1] not in chars: - option_prefix = option_string - explicit_arg = None - short_option_prefix = option_string[:2] - short_explicit_arg = option_string[2:] - - for option_string in self._option_string_actions: - if option_string == short_option_prefix: - action = self._option_string_actions[option_string] - tup = action, option_string, short_explicit_arg - result.append(tup) - elif option_string.startswith(option_prefix): - action = self._option_string_actions[option_string] - tup = action, option_string, explicit_arg - result.append(tup) - - # shouldn't ever get here - else: - self.error(_('unexpected option string: %s') % option_string) - - # return the collected option tuples - return result - - def _get_nargs_pattern(self, action): - # in all examples below, we have to allow for '--' args - # which are represented as '-' in the pattern - nargs = action.nargs - - # the default (None) is assumed to be a single argument - if nargs is None: - nargs_pattern = '(-*A-*)' - - # allow zero or one arguments - elif nargs == OPTIONAL: - nargs_pattern = '(-*A?-*)' - - # allow zero or more arguments - elif nargs == ZERO_OR_MORE: - nargs_pattern = '(-*[A-]*)' - - # allow one or more arguments - elif nargs == ONE_OR_MORE: - nargs_pattern = '(-*A[A-]*)' - - # allow any number of options or arguments - elif nargs == REMAINDER: - nargs_pattern = '([-AO]*)' - - # allow one argument followed by any number of options or arguments - elif nargs == PARSER: - nargs_pattern = '(-*A[-AO]*)' - - # all others should be integers - else: - nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs) - - # if this is an optional action, -- is not allowed - if action.option_strings: - nargs_pattern = nargs_pattern.replace('-*', '') - nargs_pattern = nargs_pattern.replace('-', '') - - # return the pattern - return nargs_pattern - - # ======================== - # Value conversion methods - # ======================== - def _get_values(self, action, arg_strings): - # for everything but PARSER args, strip out '--' - if action.nargs not in [PARSER, REMAINDER]: - arg_strings = [s for s in arg_strings if s != '--'] - - # optional argument produces a default when not present - if not arg_strings and action.nargs == OPTIONAL: - if action.option_strings: - value = action.const - else: - value = action.default - if isinstance(value, basestring): - value = self._get_value(action, value) - self._check_value(action, value) - - # when nargs='*' on a positional, if there were no command-line - # args, use the default if it is anything other than None - elif (not arg_strings and action.nargs == ZERO_OR_MORE and - not action.option_strings): - if action.default is not None: - value = action.default - else: - value = arg_strings - self._check_value(action, value) - - # single argument or optional argument produces a single value - elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: - arg_string, = arg_strings - value = self._get_value(action, arg_string) - self._check_value(action, value) - - # REMAINDER arguments convert all values, checking none - elif action.nargs == REMAINDER: - value = [self._get_value(action, v) for v in arg_strings] - - # PARSER arguments convert all values, but check only the first - elif action.nargs == PARSER: - value = [self._get_value(action, v) for v in arg_strings] - self._check_value(action, value[0]) - - # all other types of nargs produce a list - else: - value = [self._get_value(action, v) for v in arg_strings] - for v in value: - self._check_value(action, v) - - # return the converted value - return value - - def _get_value(self, action, arg_string): - type_func = self._registry_get('type', action.type, action.type) - if not _callable(type_func): - msg = _('%r is not callable') - raise ArgumentError(action, msg % type_func) - - # convert the value to the appropriate type - try: - result = type_func(arg_string) - - # ArgumentTypeErrors indicate errors - except ArgumentTypeError: - name = getattr(action.type, '__name__', repr(action.type)) - msg = str(_sys.exc_info()[1]) - raise ArgumentError(action, msg) - - # TypeErrors or ValueErrors also indicate errors - except (TypeError, ValueError): - name = getattr(action.type, '__name__', repr(action.type)) - msg = _('invalid %s value: %r') - raise ArgumentError(action, msg % (name, arg_string)) - - # return the converted value - return result - - def _check_value(self, action, value): - # converted value must be one of the choices (if specified) - if action.choices is not None and value not in action.choices: - tup = value, ', '.join(map(repr, action.choices)) - msg = _('invalid choice: %r (choose from %s)') % tup - raise ArgumentError(action, msg) - - # ======================= - # Help-formatting methods - # ======================= - def format_usage(self): - formatter = self._get_formatter() - formatter.add_usage(self.usage, self._actions, - self._mutually_exclusive_groups) - return formatter.format_help() - - def format_help(self): - formatter = self._get_formatter() - - # usage - formatter.add_usage(self.usage, self._actions, - self._mutually_exclusive_groups) - - # description - formatter.add_text(self.description) - - # positionals, optionals and user-defined groups - for action_group in self._action_groups: - formatter.start_section(action_group.title) - formatter.add_text(action_group.description) - formatter.add_arguments(action_group._group_actions) - formatter.end_section() - - # epilog - formatter.add_text(self.epilog) - - # determine help from format above - return formatter.format_help() - - def format_version(self): - import warnings - warnings.warn( - 'The format_version method is deprecated -- the "version" ' - 'argument to ArgumentParser is no longer supported.', - DeprecationWarning) - formatter = self._get_formatter() - formatter.add_text(self.version) - return formatter.format_help() - - def _get_formatter(self): - return self.formatter_class(prog=self.prog) - - # ===================== - # Help-printing methods - # ===================== - def print_usage(self, file=None): - if file is None: - file = _sys.stdout - self._print_message(self.format_usage(), file) - - def print_help(self, file=None): - if file is None: - file = _sys.stdout - self._print_message(self.format_help(), file) - - def print_version(self, file=None): - import warnings - warnings.warn( - 'The print_version method is deprecated -- the "version" ' - 'argument to ArgumentParser is no longer supported.', - DeprecationWarning) - self._print_message(self.format_version(), file) - - def _print_message(self, message, file=None): - if message: - if file is None: - file = _sys.stderr - file.write(message) - - # =============== - # Exiting methods - # =============== - def exit(self, status=0, message=None): - if message: - self._print_message(message, _sys.stderr) - _sys.exit(status) - - def error(self, message): - """error(message: string) - - Prints a usage message incorporating the message to stderr and - exits. - - If you override this in a subclass, it should not return -- it - should either exit or raise an exception. - """ - self.print_usage(_sys.stderr) - self.exit(2, _('%s: error: %s\n') % (self.prog, message)) diff --git a/.config/help b/.config/help deleted file mode 100755 index 42707d2..0000000 --- a/.config/help +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/python - -import re, os, sys, textwrap -# Formats help message -# $1 - help type: var, target or example - -text = sys.stdin.read() - -def fmt_2cols(name): - global text - - text = re.sub('(?mi)\s*\n\s+', ' ', text) - text = [ t for t in text.split('\n') if t ] - cols = [] - for t in text: - try: - (n, m) = t.split(' - ', 1) - cols.append((n.strip(), m.strip())) - except: - pass - - m = max([ len(e[0]) for e in cols ]) - ind = ' ' * m - text = "" - for c in cols: - help = textwrap.fill(c[1], initial_indent = ind, - subsequent_indent = ind) - text += ' {0:>{1}s} - {2}\n'.format(c[0],m, help.strip()) - text.strip() - - if text: - print "%s:\n%s" % (name, text) - - -def fmt_pre(): - tok = text.split('@@\n') - tok2 = [] - for t in tok: - if t.strip(): - tok2.append(t.strip()) - - for i, t in enumerate(tok2): - print 'Example %d:' % (i+1) - print t - print - -if sys.argv[1] == 'variable': - fmt_2cols('Variables') -elif sys.argv[1] == 'target': - fmt_2cols('Targets') -elif sys.argv[1] == 'example': - fmt_pre() -else: - raise Exception, 'Unknown arg: ' + sys.argv[1] diff --git a/.config/options.py b/.config/options.py deleted file mode 100644 index 885ef80..0000000 --- a/.config/options.py +++ /dev/null @@ -1,100 +0,0 @@ - -# Initialization. Create your opts here. Runs before command line processing. -def init(): - # standart autoconf options - opt_group_new('autoconf', 'Standart autoconf options') - opt_new("prefix", group = 'autoconf', - help = "install architecture-independent files", metavar='DIR', - default = lambda : '/usr') - opt_new("eprefix", group = 'autoconf', - help = "install architecture-dependent files", metavar='DIR', - default = lambda : opt('prefix')) - opt_new("bindir", group = 'autoconf', - help = "user executables", metavar='DIR', - default = lambda : opt('eprefix') + '/bin') - opt_new("sbindir", group = 'autoconf', - help = "system executables", metavar='DIR', - default = lambda : opt('eprefix') + '/sbin') - opt_new("libexecdir", group = 'autoconf', - help = "program executables", metavar='DIR', - default = lambda : opt('eprefix') + '/libexec/' + opt('project_name')) - opt_new("libdir", group = 'autoconf', - help = "object code libraries", metavar='DIR', - default = lambda : opt('eprefix') + '/lib/' + opt('project_name')) - opt_new("sysconfdir", group = 'autoconf', - help = "read-only single-machine data", metavar='DIR', - default = lambda : opt('prefix') + '/etc') - opt_new("datadir", group = 'autoconf', - help = "read-only architecture-independent data", metavar='DIR', - default = lambda : opt('prefix') + '/share/' + opt('project_name')) - opt_new("localedir", group = 'autoconf', - help = "languagetranslation files", metavar='DIR', - default = lambda : opt('datadir') + '/locale') - opt_new("includedir", group = 'autoconf', - help = "C header files", metavar='DIR', - default = lambda : opt('prefix') + '/include') - opt_new("mandir", group = 'autoconf', - help = "man documentation", metavar='DIR', - default = lambda : opt('prefix') + '/man') - opt_new("infodir", group = 'autoconf', - help = "info documentation", metavar='DIR', - default = lambda : opt('prefix') + '/info') - opt_new("localstatedir", group = 'autoconf', - help = "modifiable single-machine data in DIR", metavar='DIR', - default = lambda : opt('prefix') + '/var') - - opt_group_new('app', 'Application options', default = True) - opt_new("project_name", group = 'app', - help = "Project name", metavar='NAME', - default = 'fbpanel') - opt_new("project_version", group = 'app', - help = "Project version", metavar='VER', - default = lambda : detect_project_version()) - opt_new("sound", group = 'app', - help = "Enable sound plugin (default: autodetect)", - action = ToggleAction, default = None) - -# Logic and stuff that does not require human interaction. Runs after -# command line processing. -# Here you can do anything you want. You can create opts, delete opts, modify -# their values. Just bear in mind: whatever you do here will end up in -# config.h. -def resolve(): - # If user did not set sound on command line, it is autodetected. - if opt('sound') is None and pkg_exists('alsa', '--atleast-version=1.0.10'): - opt_set('sound', True) - - # alsa is required, only if "sound" is enabled. - if opt('sound'): - # if alsa is not installed, will raise exception - opt_new_from_pkg('alsa', 'alsa', pversion = '--atleast-version=1.0.10') - - opt_new_from_pkg('gtk2', 'gtk+-2.0', pversion = '--atleast-version=2.17') - opt_new_from_pkg('gmodule2', 'gmodule-2.0') - opt_new_from_pkg('x11', 'x11') - opt_new('cflags_extra', default='-I$(TOPDIR)/panel') - -def detect_project_name(): - # Hardcode here the name of your project - # ret = "projectname" - - # Alternatively, take top dir name as a project name - ret = os.getcwd().split('/')[-1] - - return ret - -def detect_project_version(): - ret = open('version', 'r').read().strip() - - return ret - -# Give a summary on created configuration -def report(): - str = "Configuration:\n" - str += " Sound plugin: " - if opt('sound'): - str += "yes\n" - else: - str += "no\n" - print str, - diff --git a/.config/repl.py b/.config/repl.py deleted file mode 100755 index 2194600..0000000 --- a/.config/repl.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/python - -import re, sys - -repl_dict = { -#repl_dict# -} - -def repl_func(matchobj): - key = matchobj.group(0)[1:-1] - if key in repl_dict: - return repl_dict[key] - else: - return matchobj.group(0) - - -print re.sub('@\w+@', repl_func, sys.stdin.read()) - diff --git a/.config/rules.mk b/.config/rules.mk deleted file mode 100644 index bacca3d..0000000 --- a/.config/rules.mk +++ /dev/null @@ -1,338 +0,0 @@ - -############################################### -# environment checks # -############################################### - -SHELL=/bin/bash - -.DEFAULT_GOAL := all - -define prnvar -$(warning $(origin $1) $1='$($1)') -endef - -$(TOPDIR)/config.mk: $(TOPDIR)/version $(TOPDIR)/.config/* - @echo Please run $(TOPDIR)/configure - @echo - @false -include $(TOPDIR)/config.mk - - -ifeq ($(realpath $(TOPDIR)),$(CURDIR)) -IS_TOPDIR := yes -else -IS_TOPDIR := no -endif - -IS_ALL := $(filter all,$(if $(MAKECMDGOALS),$(MAKECMDGOALS),$(.DEFAULT_GOAL))) -IS_HELP := $(filter help,$(MAKECMDGOALS)) - -ifeq ($(NV),) -export NV = $(PROJECT_NAME)-$(PROJECT_VERSION) -endif - -EMPTY := -SPACE := $(EMPTY) $(EMPTY) - -############################################### -# recurion rules # -############################################### - -RGOALS = all clean install svnignore gitignore -.PHONY : $(RGOALS) $(SUBDIRS) -$(RGOALS) : $(SUBDIRS) - -$(SUBDIRS): - $Q$(MAKE) -S -C $@ $(MAKECMDGOALS) -unexport SUBDIRS - - -$(RGOALS) $(SUBDIRS) : FORCE -FORCE: - @# - - -############################################### -# help # -############################################### - -# Help targets allow to shed a light on what your makefile does. -# Text for targets and variables will be formated into nice columns, -# while help for examples will be printed as is. -# -# You can have any number of these, if you use '::' synatx -# -# The syntax is -# help_target :: -# echo "name - explanation, every" -# echo " next line is indented" -# -# help_variable :: -# echo "name - explanation, every" -# echo " next line is indented" -# -# help_example :: -# echo "@@" -# echo "Any multi-line text formated as desired" - -help : - $Q$(MAKE) -j1 V=0 help_target | $(TOPDIR)/.config/help target - $Q$(MAKE) -j1 V=0 help_variable | $(TOPDIR)/.config/help variable -ifeq ($V,1) - $Q$(MAKE) -j1 V=0 help_example | $(TOPDIR)/.config/help example -endif - -help_target :: - @echo "help - print this help" - - -############################################### -# output customization # -############################################### - -help_variable :: - @echo "V - verbose output, if non-null" - -help_example :: - @echo "@@" - @echo "Verbose output" - @echo " make V=1" - @echo " make V=1 clean" - @echo " make V=1 tar" - -ifeq ($(MAKELEVEL),0) -export STARTDIR:=$(CURDIR) -endif - -# make V=1 - very verbose, prints all commands -# make V=0 - prints only titles [default] -ifeq ($V$(IS_HELP),1) -override Q := -else -override Q := @ -MAKEFLAGS += --no-print-directory -out := 2>/dev/null 1>/dev/null -endif -summary = @echo " $(1)" $(subst $(STARTDIR)/,,$(CURDIR)/)$(2) -summary2 = @printf " %-5s %s\n" "$(1)" "$(2)" -export V - - -############################################### -# build rules # -############################################### - -help_target :: - @echo "all - build all target" - @echo "install - install binaries" - -help_variable :: - @echo "DESTDIR - install under this dir rather " - @echo " then under /" - @echo "DEBUG - compile with debug symbols, if non-null" - -help_example :: - @echo "@@" - @echo "Installs stuff in a separate dir for easy packaging." - @echo " ./configure --prefix=/usr/local" - @echo " make" - @echo " make install DESTDIR=/tmp/tmp313231" - -help_example :: - @echo "@@" - @echo "All standard make variables, like CFLAGS, LDFLAGS or CC, " - @echo "are also supported." - @echo " make CFLAGS=-O2" - @echo " make CC=/opt/arm-gcc" - -ifeq ($(origin CFLAGS),environment) -ifeq ($(CFLAGS_orig),) -override CFLAGS_orig := $(CFLAGS) -export CFLAGS_orig -else -override CFLAGS := $(CFLAGS_orig) -endif -endif - -ifeq ($(origin CFLAGS),undefined) -ifeq ($(origin DEBUG),undefined) -CFLAGS = -O2 -Wall -Werror -else -CFLAGS = -O0 -Wall -Werror -endif -endif -ifneq ($(origin DEBUG),undefined) -override CFLAGS += -g3 -endif -override CFLAGS += -I$(TOPDIR) $(CFLAGS_EXTRA) - -# Produce local obj name from C file path -src2base = $(basename $(notdir $(1))) - -# Create rule to compile an object from source -# Parameters -# $1 - C file (eg ../some/dir/test.c) -# $2 - object file basename (eg test) -# $3 - target name (eg hello) -define objng_rules -ifneq ($(IS_ALL),) --include $(2).d -endif -$(3)_obj += $(2).o -CLEANLIST += $(2).o $(2).d -$(2).o : $(1) $(TOPDIR)/config.h - $(call summary,CC ,$$@) - $Q$(CC) $(CFLAGS) $($(3)_cflags) -c -o $$@ $$< -MMD $(out) - $Qsed -i -e 's/\s\/\S\+/ /g' $(2).d -endef - -define bin_rules -all : $(1) -CLEANLIST += $(1) - -$(foreach s,$($(1)_src),\ - $(eval $(call objng_rules,$(s),$(call src2base,$(s)),$(1)))) - -$(1) : $($(1)_obj) - $(call summary,BIN ,$$@) - $Q$(CC) $$^ $(LDFLAGS) $($(1)_libs) -o $$@ $(out) - -ifeq ($($(1)_install),) -install : $(1)_install -$(1)_install : - $Qinstall -D -m 755 -T $(1) $(DESTDIR)$(BINDIR)/$(1) -endif -endef - - -define lib_rules -all : lib$(1).so -CLEANLIST += lib$(1).so -$(eval $(1)_cflags += -fPIC) - -$(foreach s,$($(1)_src),\ - $(eval $(call objng_rules,$(s),$(call src2base,$(s)),$(1)))) - -lib$(1).so : $($(1)_obj) - $(call summary,LIB ,$$@) - $Q$(CC) $$^ $(LDFLAGS) $($(1)_libs) -shared -o $$@ $(out) - -ifeq ($($(1)_install),) -install : $(1)_install -$(1)_install : - $Qinstall -D -m 755 -T lib$(1).so $(DESTDIR)$(LIBDIR)/lib$(1).so -endif -endef - - -define ar_rules -all : lib$(1).a -CLEANLIST += lib$(1).a - - -$(foreach s,$($(1)_src),\ - $(eval $(call objng_rules,$(s),$(call src2base,$(s)),$(1)))) - -lib$(1).a : $($(1)_obj) - $(call summary,AR ,$$@) - $Q$(AR) rcs $$@ $$^ - -ifeq ($($(1)_install),) -install : $(1)_install -$(1)_install : - $Qinstall -D -m 644 -T lib$(1).a $(DESTDIR)$(LIBDIR)/lib$(1).a - -endif -endef - -ifeq ($(KVERSION),) -KVERSION := $(shell uname -r) -#export KVERSION -endif - -define kmod_rules -CLEANLIST += *.ko *.o *.mod.c .*.cmd .tmp_versions modules.order Module.symvers -all: - $(call summary,KMOD ,$(1).ko) - $Qexport KBUILD_EXTRA_SYMBOLS=$(KB_SYMBOLS); \ - make -C /lib/modules/$$(KVERSION)/build M=$(CURDIR) \ - modules $(out) -# clean: -# $Qmake -C /lib/modules/$$(KVERSION)/build M=$(CURDIR) \ -# clean $(out) - -install: - $Qmake -C /lib/modules/$$(KVERSION)/build M=$(CURDIR) \ - modules_install $(out) -endef - -% : %.in - @echo " TEXT $@" - $Q$(TOPDIR)/repl.py < $^ > $@ - - -targets = $(filter %_type,$(.VARIABLES)) -$(foreach t,$(targets),$(eval $(call $(strip $($(t)))_rules,$(t:_type=)))) - - -############################################### -# clean # -############################################### - -help_target :: - @echo "clean - clean build results" - @echo "distclean - clean build and configure results" - -ifeq ($(IS_TOPDIR),yes) -DISTCLEANLIST += config.mk config.h repl.py .config/*.pyc -endif - -clean: -ifneq (,$(CLEANLIST)) - $(call summary,CLEAN ,) - $Qrm -rf $(CLEANLIST) -endif - -distclean : clean -ifneq (,$(DISTCLEANLIST)) - $(call summary,DCLEAN ,) - $Qrm -rf $(DISTCLEANLIST) -endif - - -############################################### -# tar # -############################################### - -ifeq ($(IS_TOPDIR),yes) -help_target :: - @echo "tar - make tar archive of a project code" - -tar : - $(call summary,TAR ,/tmp/$(NV).tar.bz2) - $Q$(TOPDIR)/.config/tar.py $(if $V,-v) /tmp/$(NV).tar.bz2 -endif - - -############################################### -# misc # -############################################### - -help_target :: - @echo "svnignore - tell svn to ignore files in a cleanlist" - -svnignore: - @prop=prop-$$$$.txt; \ - for i in $(DISTCLEANLIST) $(CLEANLIST); do echo "$$i"; done > $$prop; \ - cat $$prop; \ - svn propset svn:ignore --file $$prop .; \ - rm -f $$prop - -help_target :: - @echo "gitignore - tell git to ignore files in a cleanlist" - -gitignore: - $Qfor i in $(DISTCLEANLIST) $(CLEANLIST); do echo "$$i"; \ - done > .gitignore - $Qgit add .gitignore - diff --git a/.config/tar.py b/.config/tar.py deleted file mode 100755 index f76c9ee..0000000 --- a/.config/tar.py +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/python - -import subprocess as sp -import re, tempfile -import shutil, os, sys - -################################################## -# Loging -import logging -def _init_log(): - name = 'app' - x = logging.getLogger(name) - x.setLevel(logging.WARNING) - # x.setLevel(logging.DEBUG) - h = logging.StreamHandler() - # f = logging.Formatter("%(name)s (%(funcName)s:%(lineno)d) :: %(message)s") - f = logging.Formatter("%(message)s") - h.setFormatter(f) - x.addHandler(h) - return x - -x = _init_log() - -################################################## -# Argument parsing -import argparse -p = argparse.ArgumentParser( - description='Pack project source to tar archive.', - epilog = 'Example: \n%(prog)s /tmp/proj-1.2.tar.bz2' -) - -p.add_argument('-v', dest = 'verbose', action = 'store_true', - default = False, - help = 'Print more messages [%(default)s]') -p.add_argument('-d', '--debug', dest = 'debug', action = 'store_true', - default = False, - help = 'Print debug messages [%(default)s]') -p.add_argument('tar', nargs=1, - help = 'tar file to create') - -args = p.parse_args() -if args.verbose: - x.setLevel(logging.INFO) -if args.debug: - x.setLevel(logging.DEBUG) - -################################################## -# main -def my_check_output(*popenargs, **kwargs): - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - x.debug("exec: %s", cmd) - process = sp.Popen(stdout=sp.PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - raise sp.CalledProcessError(retcode, cmd, output=output) - return output - -def svn_is_used(): - f = open('/dev/null', 'w') - p = sp.Popen('svn info'.split(), stdout = f, stderr = f) - p.wait() - return p.returncode == 0 - - -def svn_get_file_list(): - text = my_check_output('svn info -R'.split()) - files = [] - tre = '(?m)^Path: (?P.*)$(.|\s)*?^Node Kind: (?P.*)$' - for m in re.finditer(tre, text): - if m.group('type') == 'file': - files.append(m.group('path')) - return files - -def git_is_used(): - f = open('/dev/null', 'w') - p = sp.Popen('git status'.split(), stdout = f, stderr = f) - p.wait() - return p.returncode == 0 - - -def git_get_file_list(): - text = my_check_output('git ls-tree --name-only -r HEAD'.split()) - files = text.split('\n') - return files - -def none_is_used(): - f = open('/dev/null', 'w') - p = sp.Popen('make -n distclean'.split(), stdout = f, stderr = f) - p.wait() - return p.returncode == 0 - -def none_get_file_list(): - f = open('/dev/null', 'w') - p = sp.Popen('make distclean'.split(), stdout = f, stderr = f) - p.wait() - if p.returncode: - return [] - files = [] - for (dirpath, dirnames, filenames) in os.walk('.'): - if dirpath.startswith('./'): - dirpath = dirpath[2:] - elif dirpath == '.': - dirpath = '' - filenames = [ os.path.join(dirpath, f) for f in filenames ] - files.extend(filenames) - return files - -vcs = [ - { - 'name' : 'svn', - 'is_used' : svn_is_used, - 'get_file_list' : svn_get_file_list - }, - { - 'name' : 'git', - 'is_used' : git_is_used, - 'get_file_list' : git_get_file_list - }, - - # must be last entry - { - 'name' : 'none', - 'is_used' : none_is_used, - 'get_file_list' : none_get_file_list - } -] - -# Get lists of files. If VCS is used, then lists only controlled files -# otherwise lists all files -def get_file_list(): - files = [] - for v in vcs: - ret = v['is_used']() - x.debug('trying %s, ret %d', v['name'], ret) - if ret: - x.info('VCS: %s', v['name']) - files = v['get_file_list']() - # remove duplicates, if any - files = list(set(files)) - files.remove('') - files.sort() - x.debug('File list: %s', files) - if not files: - x.error('No files. Aborting') - exit(2) - return files - x.error('No files. Aborting') - exit(2) - -tar = args.tar[0] -path, name = os.path.split(tar) -nv = re.sub('.tar.*', '', name) -x.debug('tar %s, nv %s', tar, nv) -# XXX: get compresion type from extension - -files = [ nv + '/' + f for f in get_file_list() ] -files = '\n'.join(files) -x.debug('%s', files) -tdir = tempfile.mkdtemp() -odir = os.path.abspath('.') -os.chdir(tdir) -os.symlink(odir, nv) -open('filelist', 'w').write(files) -cmd = 'tar hjcf %s --files-from filelist' % (tar,) -x.debug('exec: %s', cmd) -p = sp.Popen(cmd.split()) -p.wait() -if p.returncode: - x.error('Aborting') -else: - x.info('Tar: %s', tar) - -shutil.rmtree(tdir) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b4da2c6..0000000 --- a/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -config.mk -config.h -repl.py -.config/*.pyc diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index c63a738..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,455 +0,0 @@ -6.2 -* 3367953: 'move to desktop' item in taskbar menu - -6.1 -New Features: -* 2977832: meter plugin - base plugin for icons slide show -* 2977833: battery plugin -* 2981332: volume plugin -* 2981313: Enhancements to 'tclock' plugin - calendar and transparency -* multiline taskbar: new config MinTaskHeight was added to set minimal - task/row height -* multiline launchbar: row height is MaxIconSize -* scrolling on panel changes desktops -* dclock vertical layout was implemented. It still draws digits - horizontaly if there is enough space -* new global config MaxEelemHeight was added to limit plugin elements - (eg icons, messages) height -* 993836: add GTK frame to non-transparent chart plugins - -Fixed Bugs: -* 2990621: add charging icons to battery plugin -* 2993878: set menu icons size from panel config not from gtk rc -* fixed locale/NLS issues with configure -* chart class struct was made static -* 2979388: configure broken - problems in busybox environments -* fixing variable name check in configure -* 2985792: Menu disappears too quickly -* 2990610: panel with autohide disappears when positioned at (0,0) -* 2990620: fix dclock for vertical orientation -* 2991081: do not autohide panel when menu is open -* 3002021: reduce sensitive area of hidden panel - -6.0 -* adding xlogout script -* fixing cpu and net plugins to recover after /proc read errors -* menu: new code to build system menu -* GUI configurator code was reworked -* common API to run external programs was added -* new configuration system - xconf - was introduced -* adding png icons for reboot and shutdown. They may be missing in - some icon themes. -* all svg icons were removed -* automatic profile created -* show calendar as default action in dclock -* fixed 'toggle iconfig all' algorithm -* 2863566: Allow seconds in dclock plugin -* 2972256: rebuild code upon makefile changes -* 2965428: fbpanel dissapears when configuring via GUI -* 2958238: 5.6 has bugs in configure script and fails to load plugins -* 2953357: Crashes when staring Opera - -5.8 -* moving config dir ~/.config -* automatic new profile creation -* removing app categories default icons -* dclock plugin pops up calendar if no action was set -* net plugin got detailed tooltip and color configs -* cpu plugin got detailed tooltip and color configs -* mem plugin was made -* allocating plugin's private section as part of instance malloc -* drag and drop fix in launchbar -* Fixed "2891558: widthtype=request does not work" - - -5.7 -* XRandR support (dynamic desktop geometry changes) -* Fixed "2891558: widthtype=request does not work" -* configurator redraws panel on global changes -* fixing 'toggle iconify all' algorithm - - -5.6 -* genmon plugin - displays command output in a panel -* CFLAGS propagation fix - -5.5 -* adding static build option for debugin purposes e.g to use with valgrind -* ability to set CFLAGS from command line was added. - make CFLAGS=bla-bla works correctly -* fixing memory leaks in taskbar, menu and icons plugin - -5.4 -* fb_image and icon loading code refactoring -* chart: making frame around a chart more distinguishable -* taskbar: enable tooltips in IconsOnly mode -* taskbar: build tooltips from text rather then from markup - - -5.3 -* when no icon exists in a theme, missing-image icon is substituted. theme-avare -* prevent duplicate entries in menu -* menu plugin uses simple icons, and rebuild entire menu upon theme change, - rather then creating many heavy theme-aware icons, and let them update -* cpu, net plugins: linux specific code was put into ifdefs and stub for another - case wwas created -* system menu icon was renamed to logo.png from star.png -* strip moved to separete target and not done automatically after compile -* by default make leaves output as is, to see summaries only run 'make Q=1' -* enbling dependency checking by default -* adding svn ebuild fbpanel-2009.ebuild -* adding tooltips to cpu and net plugins -* BgBox use BG_STYLE by default -* close_profile function was added to group relevant stuff -* autohide was simplified. Now it hides completly and ignoress heightWhenHidden - - - -5.2 -* fixing segfault in menu plugin -* extra spaces in lunchbar plugin were removed -* replacing obsolete GtkTooltips with GtkTooltip -* plugins' install path is set to LIBDIR/fbpanel instead of LIBEXECDIR/fbpanel -* fixing short flash of wrong background on startup - - - - -5.1 -* Tooltips can have mark-uped text, like 'Terminal' -* Cpu plugin is fixed and working -* Added general chart plugin (used by cpu and net monitors) -* Code layout was changed, new configure system and new makefiles set was - adopted -* fixed segfault in taskbar plugin -* background pixmap drawing speed ups and bugfixes - -4.13 -New Features: -* support for "above all" and "below all" layering states. Global section - was added string variable - Layer = None | Above | Below -* to speed start-up, panel does not have window icon, only configuator window has -* Control-Button3 click launches configureation dialog -* taskbar was changed to propagate Control-Button3 clicks to parent window i.e to panel -* launchbar was changed to propagate Control-Button3 clicks to parent window -* pager was changed to propagate Control-Button3 clicks to parent window -* dclock was changed to propagate Control-Button3 clicks to parent window -* menu was changed to propagate Control-Button3 clicks to parent window -* normal support for round corners. Config file gets new global integer option - RoundCornersRadius -* system tray transparency fix -* clock startup delay was removed -* menu: fixed segfault caused by timeout func that used stale pointer - - - -4.12 -New Features: -* smooth icon theme change without panel reload -* autohide. Config section is part of 'Global' section - autoHide = false - heightWhenHidden = 2 -* 3 sec delayed menu creation to improve start-up time - -Fixed Bugs: -* icons, taskbar do not free all tasks when destroyed - - -4.11 -Fixed Bugs: -* black background when no bg pixmap and transparency is unset - -4.10 -New Fetures: -* tclock: dclock was renamed to tclock = text clock -* dclock: digital blue clock. adopted from blueclock by - Jochen Baier -* dclock: custom clock color can be set with 'color' option - Plugin { - type = dclock - config { - TooltipFmt = %A %x - Action = xterm & - color = wheat - } - } - -* menu: items are sorted by name -* menu: icon size set to 22 -* launchbar: drag-n-drop now accepts urls draged from web browsers -* style changes are grouped and only last of them is processed - -Fixed Bugs: -* menu: forgoten g_free's were added -* 1723786: linkage problems with --as-needed flag -* 1724852: crash if root bg is not set -* WM_STATE usage is dropped. NET_WM_STATE is used instead. affected plugins are - taskbar and pager -* fixed bug where pager used unupdated panel->desknum instead of pager->desknum -* all Cardinal vars were changed to guint from int -* bug in Makefile.common that generated wrong names in *.dep files -* style changes are grouped and only last of them is processed - -4.9 -* new menu placement to not cover panel; used in menu and taskbar -* taskbar: icons were added to task's menu (raise, iconify, close) -* access to WM_HINTS is done via XGetWMHints only and not via get_xa_property; - in taskbar it fixes failure to see existing icon pixmap -* 1704709: config checks for installed devel packages - -4.8 -* help text in configurator was made selectable -* pager shows desktop wallpaper -* expanding tilda (~) in action field in config files -* menu icons size was set to 24 from 22 to avoid scaling -* avoid re-moving panel to same position -* plugins section in configurator dialog suggests to edit config manually -* taskbar vertical layout was fixed -* taskbar 'icons only' mode was optimized -* fbpanel config window has nice "star" icon - -4.7 -New Feature -* Build application menu from *.desktop files -* Using themed icons. Change icon theme and see fbpanel updates itself -* default config files were updates to use new functionality - -4.6 -New Features -* [ 1295234 ] Detect Window "Urgency". -* Raise window when drag target is over its name in taskbar -* fixing meory leaks from XGetWindowProperty. -* fix urgency code to catch up urgency of new windows -* taskbar: correct position of task's label -* taskbar: remove extra spaces -* taskbar: do not create event box beneath task button -* taskbar: use default expose method in gtk_bar -* taskbar; use default expose method in task button -* taskbar: cleaning up dnd code -* launchbar: visual feedback on button press - -4.5 -Fixed bugs -* Makefile.common overwrite/ignore CFLAGS and LDFLAGS env. variables -* rebuild dependancy Makefiles (*.dep) if their prerequisits were changed -* fixing gcc-4.1 compile warnings about signess -* removing tar from make's recursive goals -* fixing NET_WM_STRUT code to work on 64 bit platforms - -New features -* porting plugins/taskbar to 64 bit -* porting plugins/icons to 64 bit -* adding LDFLAGS=-Wl,-O1 to Makefile -* adding deskno2 plugin; it shows current desktop name and allow to scroll over available desktops -* applying patch [ 1062173 ] NET_ACTIVE_WINDOW support -* hiding tray when there are no tray icons -* remove extra space around tray -* using new icons from etiquette theme. droping old ones - -4.4 -New Feature -* 64-bit awarenes - -4.3 -New Feature -* [1208377] raise and iconify windows with mouse wheel -* [1210550] makefile option to compile plugins statically -* makefile help was added. run 'make help' to get it -* deskno gui changes - -Fixed Bugs -* deskno can't be staticaly compiled -* typo fixes -* Makefile errors for shared and static plugin build - -4.2 -Fixed Bugs -* [1161921] menu image is too small -* [1106944] ERROR used before int declaration breaks build -* [1106946] -isystem needs space? -* [1206383] makefile fails if CFLAGS set on command line -* [1206385] DnD in launchbar fails if url has a space -* fixed typos in error messages - -New Feature -* New code for panel's buttons. Affected plugins are wincmd, launchbar and menu -* Depreceted option menu widget was replaced by combo box -* sys tray is packed into shadowed in frame -* pad is inserted betwean tasks in a taskbar -* clock was made flat - -4.1 -New Feature -* gui configuration utility -* transparency bug fixes - -4.0 -New Feature -* plugins get root events via panel's proxy rather then directly -* added configure option to disable cpu plugin compilation - -3.18 -New Feature -* [ 1071997 ] deskno - plugin that displays current workspace number -Fixed Bugs -* [ 1067515 ] Fixed bug with cpu monitor plugin - - -3.17 -Fixed Bugs -* [ 1063620 ] 3.16 crashes with gaim 1.0.2 sys tray applet -New Feature -* [ 1062524 ] CPU usage monitor - - -3.16 -New Feature -* taskbar does not change window icons anymore. -* invisible (no-gui) plugin type was introduced -* icons plugin was implemented. it is invisible plugin used to changes - window icons with desktop-wide effect. - - -3.15 -Fixed Bugs -* [ 1061036 ] segfault if tray restarted - -3.14 -New Feature -* [ 1010699 ] A space-filler plugin -* [ 1057046 ] transparency support -* all static plugins were converted to dlls -* added -verbose command line option -Fixed Bugs -* dynamic module load fix - -3.13 -New Feature -* [ 953451 ] Add include functionality for menu config file. -Fixed Bugs -* [ 1055257 ] crash with nautilus+openbox - -3.12 -New Features -* [ 976592 ] Right-click Context menu for the taskbar - -3.11 -* fixed [ 940441 ] pager loose track of windows - -3.10 -* fix for "996174: dclock's 'WARNING **: Invalid UTF8 string'" -* config file fix - -3.9 -* fix bg change in non transparent mode -* enable icon only in taskbar -* ensure all-desktop presence if starting before wm (eg openbox) -* wincmd segfault fix - -3.8 -* warnings clean-up -* X11 memory leacher was fixed -* taskbar can be set to show only mapped/iconified and wins from other desktops -* transparency initial support -* gtkbar was ported to gtk2, so fbpanel is compiled with GTK_DISABLE_DEPRECETED -* initial dll support - -3.7 -* rounded corners (optional) -* taskbar view fix - -3.6 -* taskbar icon size fix -* menu icon size fix -* pager checks for drawable pixmap - -3.5 -* Drag-n-Drop for launchbar -* menu plugin -* removed limith for max task size in taskbar - -3.4 -* gtk2.2 linkage fix -* strut fix -* launchbar segfault on wrong config fix -* '&' at the end of action var in launchbar config is depreciated - -3.3 -* taskbar icon size fix - -3.2 -* scroll mouse in pager changes desktops -* packaging and makefiles now are ready for system wide install - additionally ./configure was implemented -* systray checks for another tray already running - -3.1 -* improving icon quility in taskbar -* system tray (aka notification area) support -* NET_WM_STRUT_PARTIAL and NET_WM_STRUT were implmented -* taskbar update icon image on every icon change - -3.0 -* official version bump :-) - -3.0-rc-1 -* porting to GTK2+. port is based on phako's patch - "[ 678749 ] make it compile and work with gtk2" - - -2.2 -* support for XEmbed docklets via gtktray utility - -2.1 -* tray plugin was written -* documentation update -* web site update - -2.0 -* complete engine rewrite -* new plugin API -* pager fixes - -1.4 -* bug-fixes for pager plugin - -1.3 -* middle-click in taskbar will toggle shaded state of a window -* added image plugin - this is simple plugin that just shows an image -* pager eye-candy fixes -* close_module function update - -1.2 -* we've got new module - pager! Yeeaa-Haa!! -* segfault on wrong config file was fixed - -1.1 -* parsing engine was rewritten -* modules' static variables were converted to mallocs -* configurable size and postion of a panel -* ability to specify what modules to load -* '~' is accepted in config files -* - - -1.0 -* 1.0-rc2 was released as 1.0 - -1.0-rc2 -* taskbar config file was added an option to switch tooltips on/off -* added tooltips to taskbar (thanks to Joe MacDonald joe@deserted.net) - -1.0-rc1 -* copyright comments were changed - -1.0-rc0 -* added _NET_WM_STRUT support -* panel now is unfocusable. this fixes iconify bug under sawfish -* panel's height is calculated at run-time, instead of fixed 22 - -0.11 -* improved EWMH/NETWM support -* added openbox support -* added clock customization (thanks to Tooar tooar@gmx.net) -* README was rewrited -* bug fixes diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f8790f..ababd12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,33 @@ +## Version: 7.2 +* Add cmake rules to build fbpanel +* Get rid of previous python2-bsed build system +* Update documetation +* Extend max amount of buttons 20->40 on launchbar + + +## Version: 7.1 + +Date: 2020-06-07 20:20:00 + +* Reimplement 'Xinerama support' patch for 7.0 +* Fix some deprecation warnings +* Added plugin to display battery usage in text form +* Added Italian translation +* Added icon drawing support to the pager plugin +* Some other assorted fixes + ## Version: 7.0 + Date: 2015-12-05 08:25:36 - * [#12] fix menu position for top panel - * [#11] new plugin: user menu with gravatar icon - * [#8] Fix for issue #5 (make battery plugin work with /sys) - * [#6] Rounded corners don't work with widthtype=request - * [#5] make battery plugin work with /sys - * [#4] update README - * [#2] Include option for vertical (y) and horizontal (x) margin +* [#12] fix menu position for top panel +* [#11] new plugin: user menu with gravatar icon +* [#8] Fix for issue #5 (make battery plugin work with /sys) +* [#6] Rounded corners don't work with widthtype=request +* [#5] make battery plugin work with /sys +* [#4] update README +* [#2] Include option for vertical (y) and horizontal (x) margin [#12]: https://github.com/aanatoly/fbpanel/issues/12 [#11]: https://github.com/aanatoly/fbpanel/issues/11 @@ -17,3 +36,577 @@ Date: 2015-12-05 08:25:36 [#5]: https://github.com/aanatoly/fbpanel/issues/5 [#4]: https://github.com/aanatoly/fbpanel/issues/4 [#2]: https://github.com/aanatoly/fbpanel/issues/2 + + +## Version: 6.2 + +* 3367953: 'move to desktop' item in taskbar menu + + +## Version: 6.1 + +New Features: + +* 2977832: meter plugin - base plugin for icons slide show +* 2977833: battery plugin +* 2981332: volume plugin +* 2981313: Enhancements to 'tclock' plugin - calendar and transparency +* multiline taskbar: new config MinTaskHeight was added to set minimal + task/row height +* multiline launchbar: row height is MaxIconSize +* scrolling on panel changes desktops +* dclock vertical layout was implemented. It still draws digits + horizontaly if there is enough space +* new global config MaxEelemHeight was added to limit plugin elements + (eg icons, messages) height +* 993836: add GTK frame to non-transparent chart plugins + +Fixed Bugs: + +* 2990621: add charging icons to battery plugin +* 2993878: set menu icons size from panel config not from gtk rc +* fixed locale/NLS issues with configure +* chart class struct was made static +* 2979388: configure broken - problems in busybox environments +* fixing variable name check in configure +* 2985792: Menu disappears too quickly +* 2990610: panel with autohide disappears when positioned at (0,0) +* 2990620: fix dclock for vertical orientation +* 2991081: do not autohide panel when menu is open +* 3002021: reduce sensitive area of hidden panel + + +## Version: 6.0 + +* adding xlogout script +* fixing cpu and net plugins to recover after /proc read errors +* menu: new code to build system menu +* GUI configurator code was reworked +* common API to run external programs was added +* new configuration system - xconf - was introduced +* adding png icons for reboot and shutdown. They may be missing in some icon themes. +* all svg icons were removed +* automatic profile created +* show calendar as default action in dclock +* fixed 'toggle iconfig all' algorithm +* 2863566: Allow seconds in dclock plugin +* 2972256: rebuild code upon makefile changes +* 2965428: fbpanel dissapears when configuring via GUI +* 2958238: 5.6 has bugs in configure script and fails to load plugins +* 2953357: Crashes when staring Opera + + +## Version: 5.8 + +* moving config dir ~/.config +* automatic new profile creation +* removing app categories default icons +* dclock plugin pops up calendar if no action was set +* net plugin got detailed tooltip and color configs +* cpu plugin got detailed tooltip and color configs +* mem plugin was made +* allocating plugin's private section as part of instance malloc +* drag and drop fix in launchbar +* Fixed "2891558: widthtype=request does not work" + + +## Version: 5.7 + +* XRandR support (dynamic desktop geometry changes) +* Fixed "2891558: widthtype=request does not work" +* configurator redraws panel on global changes +* fixing 'toggle iconify all' algorithm + + +## Version: 5.6 + +* genmon plugin - displays command output in a panel +* CFLAGS propagation fix + +## Version: 5.5 + +* adding static build option for debugin purposes e.g to use with valgrind +* ability to set CFLAGS from command line was added. + make CFLAGS=bla-bla works correctly +* fixing memory leaks in taskbar, menu and icons plugin + +## Version: 5.4 + +* fb_image and icon loading code refactoring +* chart: making frame around a chart more distinguishable +* taskbar: enable tooltips in IconsOnly mode +* taskbar: build tooltips from text rather then from markup + + +## Version: 5.3 + +* when no icon exists in a theme, missing-image icon is substituted. theme-avare +* prevent duplicate entries in menu +* menu plugin uses simple icons, and rebuild entire menu upon theme change, rather then creating many heavy theme-aware icons, and let them update +* cpu, net plugins: linux specific code was put into ifdefs and stub for another case was created +* system menu icon was renamed to logo.png from star.png +* strip moved to separete target and not done automatically after compile +* by default make leaves output as is, to see summaries only run 'make Q=1' +* enbling dependency checking by default +* adding svn ebuild fbpanel-2009.ebuild +* adding tooltips to cpu and net plugins +* BgBox use BG_STYLE by default +* close_profile function was added to group relevant stuff +* autohide was simplified. Now it hides completly and ignoress heightWhenHidden + + +## Version: 5.2 + +* fixing segfault in menu plugin +* extra spaces in lunchbar plugin were removed +* replacing obsolete GtkTooltips with GtkTooltip +* plugins' install path is set to LIBDIR/fbpanel instead of LIBEXECDIR/fbpanel +* fixing short flash of wrong background on startup + + +## Version: 5.1 + +* Tooltips can have mark-uped text, like 'Terminal' +* Cpu plugin is fixed and working +* Added general chart plugin (used by cpu and net monitors) +* Code layout was changed, new configure system and new makefiles set was adopted +* fixed segfault in taskbar plugin +* background pixmap drawing speed ups and bugfixes + +## Version: 4.13 + +New Features: + +* support for "above all" and "below all" layering states. Global section + was added string variable + Layer = None | Above | Below +* to speed start-up, panel does not have window icon, only configuator window has +* Control-Button3 click launches configureation dialog +* taskbar was changed to propagate Control-Button3 clicks to parent window i.e to panel +* launchbar was changed to propagate Control-Button3 clicks to parent window +* pager was changed to propagate Control-Button3 clicks to parent window +* dclock was changed to propagate Control-Button3 clicks to parent window +* menu was changed to propagate Control-Button3 clicks to parent window +* normal support for round corners. Config file gets new global integer option - RoundCornersRadius +* system tray transparency fix +* clock startup delay was removed +* menu: fixed segfault caused by timeout func that used stale pointer + + +## Version: 4.12 + +New Features: + +* smooth icon theme change without panel reload +* autohide. Config section is part of 'Global' section + +```ini + autoHide = false + heightWhenHidden = 2 +``` + +* 3 sec delayed menu creation to improve start-up time + +Fixed Bugs: + +* icons, taskbar do not free all tasks when destroyed + + +## Version: 4.11 + +Fixed Bugs: + +* black background when no bg pixmap and transparency is unset + + +## Version: 4.10 + +New Features: + +* tclock: dclock was renamed to tclock = text clock +* dclock: digital blue clock. adopted from blueclock by Jochen Baier +* dclock: custom clock color can be set with 'color' option + +```json + Plugin { + type = dclock + config { + TooltipFmt = %A %x + Action = xterm & + color = wheat + } + } +``` + +* menu: items are sorted by name +* menu: icon size set to 22 +* launchbar: drag-n-drop now accepts urls draged from web browsers +* style changes are grouped and only last of them is processed + +Fixed Bugs: + +* menu: forgoten g_free's were added +* 1723786: linkage problems with --as-needed flag +* 1724852: crash if root bg is not set +* WM_STATE usage is dropped. NET_WM_STATE is used instead. affected plugins are + taskbar and pager +* fixed bug where pager used unupdated panel->desknum instead of pager->desknum +* all Cardinal vars were changed to guint from int +* bug in Makefile.common that generated wrong names in *.dep files +* style changes are grouped and only last of them is processed + + +## Version: 4.9 + +* new menu placement to not cover panel; used in menu and taskbar +* taskbar: icons were added to task's menu (raise, iconify, close) +* access to WM_HINTS is done via XGetWMHints only and not via get_xa_property; in taskbar it fixes failure to see existing icon pixmap +* 1704709: config checks for installed devel packages + + +## Version: 4.8 + +* help text in configurator was made selectable +* pager shows desktop wallpaper +* expanding tilda (~) in action field in config files +* menu icons size was set to 24 from 22 to avoid scaling +* avoid re-moving panel to same position +* plugins section in configurator dialog suggests to edit config manually +* taskbar vertical layout was fixed +* taskbar 'icons only' mode was optimized +* fbpanel config window has nice "star" icon + + +## Version: 4.7 + +New Feature + +* Build application menu from *.desktop files +* Using themed icons. Change icon theme and see fbpanel updates itself +* default config files were updates to use new functionality + + +## Version: 4.6 + +New Features + +* [ 1295234 ] Detect Window "Urgency". +* Raise window when drag target is over its name in taskbar +* fixing meory leaks from XGetWindowProperty. +* fix urgency code to catch up urgency of new windows +* taskbar: correct position of task's label +* taskbar: remove extra spaces +* taskbar: do not create event box beneath task button +* taskbar: use default expose method in gtk_bar +* taskbar; use default expose method in task button +* taskbar: cleaning up dnd code +* launchbar: visual feedback on button press + + +## Version: 4.5 + +Fixed bugs + +* Makefile.common overwrite/ignore CFLAGS and LDFLAGS env. variables +* rebuild dependancy Makefiles (*.dep) if their prerequisits were changed +* fixing gcc-4.1 compile warnings about signess +* removing tar from make's recursive goals +* fixing NET_WM_STRUT code to work on 64 bit platforms + +New features + +* porting plugins/taskbar to 64 bit +* porting plugins/icons to 64 bit +* adding LDFLAGS=-Wl,-O1 to Makefile +* adding deskno2 plugin; it shows current desktop name and allow to scroll over available desktops +* applying patch [ 1062173 ] NET_ACTIVE_WINDOW support +* hiding tray when there are no tray icons +* remove extra space around tray +* using new icons from etiquette theme. droping old ones + + +## Version: 4.4 + +New Feature + +* 64-bit awarenes + + +## Version: 4.3 + +New Feature + +* [1208377] raise and iconify windows with mouse wheel +* [1210550] makefile option to compile plugins statically +* makefile help was added. run 'make help' to get it +* deskno gui changes + +Fixed Bugs + +* deskno can't be staticaly compiled +* typo fixes +* Makefile errors for shared and static plugin build + +## Version: 4.2 + +Fixed Bugs + +* [1161921] menu image is too small +* [1106944] ERROR used before int declaration breaks build +* [1106946] -isystem needs space? +* [1206383] makefile fails if CFLAGS set on command line +* [1206385] DnD in launchbar fails if url has a space +* fixed typos in error messages + +New Feature + +* New code for panel's buttons. Affected plugins are wincmd, launchbar and menu +* Depreceted option menu widget was replaced by combo box +* sys tray is packed into shadowed in frame +* pad is inserted betwean tasks in a taskbar +* clock was made flat + +## Version: 4.1 + +New Feature + +* gui configuration utility +* transparency bug fixes + +## Version: 4.0 + +New Feature + +* plugins get root events via panel's proxy rather then directly +* added configure option to disable cpu plugin compilation + +## Version: 3.18 + +New Feature + +* [ 1071997 ] deskno - plugin that displays current workspace number + +Fixed Bugs + +* [ 1067515 ] Fixed bug with cpu monitor plugin + + +## Version: 3.17 + +Fixed Bugs + +* [ 1063620 ] 3.16 crashes with gaim 1.0.2 sys tray applet + +New Feature + +* [ 1062524 ] CPU usage monitor + + +## Version: 3.16 +New Feature +* taskbar does not change window icons anymore. +* invisible (no-gui) plugin type was introduced +* icons plugin was implemented. it is invisible plugin used to changes + window icons with desktop-wide effect. + + +## Version: 3.15 + +Fixed Bugs + +* [ 1061036 ] segfault if tray restarted + + +## Version: 3.14 + +New Feature +* [ 1010699 ] A space-filler plugin +* [ 1057046 ] transparency support +* all static plugins were converted to dlls +* added -verbose command line option + +Fixed Bugs + +* dynamic module load fix + +## Version: 3.13 + +New Feature + +* [ 953451 ] Add include functionality for menu config file. + +Fixed Bugs + +* [ 1055257 ] crash with nautilus+openbox + +## Version: 3.12 + +New Features + +* [ 976592 ] Right-click Context menu for the taskbar + + +## Version: 3.11 + +* fixed [ 940441 ] pager loose track of windows + + +## Version: 3.10 + +* fix for "996174: dclock's 'WARNING **: Invalid UTF8 string'" +* config file fix + + +## Version: 3.9 + +* fix bg change in non transparent mode +* enable icon only in taskbar +* ensure all-desktop presence if starting before wm (eg openbox) +* wincmd segfault fix + + +## Version: 3.8 + +* warnings clean-up +* X11 memory leacher was fixed +* taskbar can be set to show only mapped/iconified and wins from other desktops +* transparency initial support +* gtkbar was ported to gtk2, so fbpanel is compiled with GTK_DISABLE_DEPRECETED +* initial dll support + + +## Version: 3.7 + +* rounded corners (optional) +* taskbar view fix + + +## Version: 3.6 + +* taskbar icon size fix +* menu icon size fix +* pager checks for drawable pixmap + + +## Version: 3.5 + +* Drag-n-Drop for launchbar +* menu plugin +* removed limith for max task size in taskbar + + +## Version: 3.4 + +* gtk2.2 linkage fix +* strut fix +* launchbar segfault on wrong config fix +* '&' at the end of action var in launchbar config is depreciated + + +## Version: 3.3 + +* taskbar icon size fix + + +## Version: 3.2 + +* scroll mouse in pager changes desktops +* packaging and makefiles now are ready for system wide install additionally ./configure was implemented +* systray checks for another tray already running + + +## Version: 3.1 + +* improving icon quility in taskbar +* system tray (aka notification area) support +* NET_WM_STRUT_PARTIAL and NET_WM_STRUT were implmented +* taskbar update icon image on every icon change + + +## Version: 3.0 + +* official version bump :-) + + +## Version: 3.0-rc-1 + +* porting to GTK2+. port is based on phako's patch "[ 678749 ] make it compile and work with gtk2" + + +## Version: 2.2 + +* support for XEmbed docklets via gtktray utility + + +## Version: 2.1 + +* tray plugin was written +* documentation update +* web site update + + +## Version: 2.0 + +* complete engine rewrite +* new plugin API +* pager fixes + + +## Version: 1.4 + +* bug-fixes for pager plugin + + +## Version: 1.3 + +* middle-click in taskbar will toggle shaded state of a window +* added image plugin - this is simple plugin that just shows an image +* pager eye-candy fixes +* close_module function update + + +## Version: 1.2 + +* we've got new module - pager! Yeeaa-Haa!! +* segfault on wrong config file was fixed + + +## Version: 1.1 + +* parsing engine was rewritten +* modules' static variables were converted to mallocs +* configurable size and postion of a panel +* ability to specify what modules to load +* '~' is accepted in config files + + +## Version: 1.0 + +* 1.0-rc2 was released as 1.0 + + +## Version: 1.0-rc2 + +* taskbar config file was added an option to switch tooltips on/off +* added tooltips to taskbar (thanks to Joe MacDonald joe@deserted.net) + + +## Version: 1.0-rc1 + +* copyright comments were changed + + +## Version: 1.0-rc0 + +* added _NET_WM_STRUT support +* panel now is unfocusable. this fixes iconify bug under sawfish +* panel's height is calculated at run-time, instead of fixed 22 + + +## Version: 0.11 + +* improved EWMH/NETWM support +* added openbox support +* added clock customization (thanks to Tooar tooar@gmx.net) +* README was rewrited +* bug fixes diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a1c8cfb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.5) +project(fbpanel VERSION 7.0 LANGUAGES C) +set(CMAKE_VERBOSE_MAKEFILE OFF) +set(CMAKE_COLOR_MAKEFILE OFF) +set(CMAKE_PROJECT_VERSION "7.2") + +include(GNUInstallDirs) +find_package(X11 REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(MODULES REQUIRED gmodule-2.0 gtk+-2.0 ) + +# we need this header in order to build target +configure_file ( "${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_SOURCE_DIR}/config.h") +configure_file ( "${PROJECT_SOURCE_DIR}/version.in" "${PROJECT_SOURCE_DIR}/version") + +file(GLOB FBPANEL_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} panel/*.c) +file(GLOB FBPANEL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} panel/*.h) + +# setup fbpanel itself +add_executable (fbpanel ${FBPANEL_SOURCES} ${FBPANEL_HEADERS}) +target_compile_options (fbpanel PRIVATE -MMD) +target_include_directories(fbpanel PUBLIC panel . ) +target_include_directories(fbpanel SYSTEM PRIVATE ${X11_INCLUDE_DIRS} ${MODULES_INCLUDE_DIRS}) +# export symbols during link process of fbpanel because plugins use fbpanel binary as library. +target_link_libraries (fbpanel PRIVATE -lm ${X11_LIBRARIES} ${MODULES_LIBRARIES} -Wl,--export-dynamic) + +# make a list of fbpanel plugins +set(PLUGINS battery batterytext cpu deskno genmon image mem2 meter pager space tclock volume chart dclock deskno2 icons launchbar mem menu net separator taskbar tray user wincmd) + +foreach(PLUGIN ${PLUGINS}) + file(GLOB PLUGIN_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} plugins/${PLUGIN}/*.c) + file(GLOB PLUGIN_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} plugins/${PLUGIN}/*.h) + add_library (${PLUGIN} SHARED ${PLUGIN_SOURCES} ${PLUGIN_HEADERS} ${FBPANEL_HEADERS}) + target_include_directories(${PLUGIN} PUBLIC panel .) +# put system here to suppress deprecation warns relating gtk2 and newer glib + target_include_directories(${PLUGIN} SYSTEM PRIVATE ${MODULES_INCLUDE_DIRS}) +# target_link_libraries (${PLUGIN} PRIVATE ${X11_LIBRARIES} ${MODULES_LIBRARIES} -Wl,--no-undefined) + target_link_libraries (${PLUGIN} PRIVATE ${X11_LIBRARIES} ${MODULES_LIBRARIES} -Wl,--warn-unresolved-symbols) + target_compile_definitions(${PLUGIN} PUBLIC PLUGIN) + target_compile_options (${PLUGIN} PUBLIC -pthread -MMD) +endforeach() + +# workout manpage +set(DATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/config") +configure_file ( + "${PROJECT_SOURCE_DIR}/data/man/fbpanel.1.in" + "${PROJECT_BINARY_DIR}/fbpanel.1" +) + +# workout default config +file(READ "${PROJECT_SOURCE_DIR}/data/config/default.in" defaultconfig) +string(REPLACE "%%datadir%%" "${CMAKE_INSTALL_FULL_DATAROOTDIR}" defaultconfig ${defaultconfig}) +string(REPLACE "@libexecdir@" "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${PROJECT_NAME}" defaultconfig ${defaultconfig}) +file(WRITE "${PROJECT_BINARY_DIR}/default" ${defaultconfig}) + +# workout pager config +configure_file ( + "${PROJECT_SOURCE_DIR}/data/config/pager.in" + "${PROJECT_BINARY_DIR}/pager" +) + +# workout make_profile script +set(datadir "${CMAKE_INSTALL_FULL_DATAROOTDIR}/${PROJECT_NAME}") +configure_file ( + "${PROJECT_SOURCE_DIR}/exec/make_profile.in" + "${PROJECT_BINARY_DIR}/make_profile" + @ONLY +) + +# create "make install" rules in one place +install(PROGRAMS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}" DESTINATION "${CMAKE_INSTALL_BINDIR}") +foreach(PLUGIN ${PLUGINS}) + install(PROGRAMS "${PROJECT_BINARY_DIR}/lib${PLUGIN}.so" DESTINATION "${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}") +endforeach() +set(DOCS CHANGELOG.md COPYING CREDITS INSTALL.md README.md) +foreach(DOC ${DOCS}) + install(FILES "${PROJECT_SOURCE_DIR}/${DOC}" DESTINATION "${CMAKE_INSTALL_DOCDIR}-${CMAKE_PROJECT_VERSION}") +endforeach() +install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.1" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") +install(DIRECTORY "${PROJECT_SOURCE_DIR}/data/images" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}" PATTERN "Makefile" EXCLUDE) +install(FILES "${PROJECT_BINARY_DIR}/default" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/config") +install(FILES "${PROJECT_BINARY_DIR}/pager" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/config") +install(PROGRAMS "${PROJECT_SOURCE_DIR}/exec/xlogout" DESTINATION "${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}") +install(PROGRAMS "${PROJECT_BINARY_DIR}/make_profile" DESTINATION "${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}") +install(FILES "${PROJECT_SOURCE_DIR}/po/fr_FR.UTF-8.mo" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/locale/fr/LC_MESSAGES" RENAME "${PROJECT_NAME}.mo") +install(FILES "${PROJECT_SOURCE_DIR}/po/ru_RU.UTF-8.mo" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/locale/ru/LC_MESSAGES" RENAME "${PROJECT_NAME}.mo") +install(FILES "${PROJECT_SOURCE_DIR}/po/it_IT.UTF-8.mo" DESTINATION "${CMAKE_INSTALL_FULL_DATADIR}/locale/it/LC_MESSAGES" RENAME "${PROJECT_NAME}.mo") diff --git a/COPYING b/COPYING index bc80143..a3fd416 100644 --- a/COPYING +++ b/COPYING @@ -1,3 +1,4 @@ +Copyright (C) 2020 Sergei Fedosoff (aka eleksir) Copyright (C) 2002 Anatoly Asviyan (aka Arsen) Copyright (C) 2000 Peter Zelezny diff --git a/CREDITS b/CREDITS index bccdeea..4932a86 100644 --- a/CREDITS +++ b/CREDITS @@ -19,3 +19,5 @@ The first version of fBpanel was started as hacking around fSpanel :-) Nice battery icons for battery meter plugin were taken from http://rocketdock.com/addon/docklets/9523 + +All people who made or will make any contribution to this project. diff --git a/INSTALL.md b/INSTALL.md index 329a09d..bc01efb 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,27 +1,19 @@ # Installation: -## User install -Build and install it -``` -./configure --prefix=$HOME/.local -make -make install -``` -Then add `~/.local/bin/` to your `PATH`. Add this line to `~/.bashrc` -``` -export PATH=$HOME/.local/bin:$PATH -``` +## Requirements + +You need recent GTK-2.0 (development of gtk-2 stopped a while ago, so in most cases you'll have correct one), at least 2.17. +Also cmake-3.5.2+ required and glib2, the most elder version tested is 2.4.46, but it looks like earlier ones might work too. + ## System Install + Build and install it -``` -./configure -make +```sh +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RELWITHDEBINFO .. +make -j$(nproc) su -c "make install" ``` - -# Dependencies -Deps: - * core - gtk2 2.17 or higher - * plugin `foo` - bar 1.0 diff --git a/Makefile b/Makefile deleted file mode 100644 index 78fd88c..0000000 --- a/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := . - -SUBDIRS := data \ - exec \ - panel \ - plugins \ - po \ - scripts - -include $(TOPDIR)/.config/rules.mk diff --git a/NOTES b/NOTES deleted file mode 100644 index 184965c..0000000 --- a/NOTES +++ /dev/null @@ -1,21 +0,0 @@ -6.2 - -6.1 -This release features major enhancements and bug fixes, namely: -* new plugin - laptop battery monitor -* new plugin - volume control -* multiline placement of elements in taskbar and launchbar -* digital clock in vertical layouts draws hours above minutes -* fixed compilation issues in busybox environments -* fixed locale/NLS issues in configure -* autohide was improved - -6.0 -This release features minor enhancements and bug fixes, namely: -* redesign of configuration engine to be faster and simpler -* script to logout from user session -* ability to show seconds in dclock plugin -* bug fixes in mem, taskbar and menu plugins -* usage of current icon theme was ensured and private icons were - removed from package - diff --git a/README.md b/README.md index 605d51c..6df665f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,27 @@ # fbpanel A lightweight gtk2 panel for Linux desktop. -Please visit [project web site](http://aanatoly.github.io/fbpanel/) -for more information. +## Story +Looks like previous maintainer of this project gaveup and freeze any development 4+ years ago. -![shot](/data/shot.png) +## This place +This repository is an attempt to gather different efforts on maintenance of fbpanel in one place. + +## Branches +Mainline branch is tested and known as working. All PR (if any) should be made to this btanch. + +Master branch is where development happens. + +## What is this all about? +Just for fun. Really. + +## Help? +If you have an idea or fix, please make PR. I'll review it carefully and try to merge if it worth. + +## Screenshot + +![screenshot](/data/shot.png) + +## Links + +[Original project web site](http://aanatoly.github.io/fbpanel/) diff --git a/TODO b/TODO new file mode 100644 index 0000000..62dd4f3 --- /dev/null +++ b/TODO @@ -0,0 +1,11 @@ +TODO List + +* Add first draft of Centos-7 spec-file (as an example) +* Remove former github pages from this particular repo and move it to separate one +* Split out libfbpanel and put there functions that are shared among fbpanel itself and its plugins + +Help wanted: +* update ebuilds +* new debian package stuff +* other packaging artifacts for different systems and distributions +* gtk-3 port diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..b14c738 --- /dev/null +++ b/config.h.in @@ -0,0 +1,7 @@ +#define PREFIX "@CMAKE_INSTALL_PREFIX@" +#define LIBEXECDIR "@CMAKE_INSTALL_FULL_LIBEXECDIR@/@PROJECT_NAME@" +#define LIBDIR "@CMAKE_INSTALL_FULL_LIBDIR@/@PROJECT_NAME@" +#define DATADIR "@CMAKE_INSTALL_FULL_DATADIR@/@PROJECT_NAME@" +#define LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@" +#define PROJECT_NAME "@CMAKE_PROJECT_NAME@" +#define PROJECT_VERSION "@CMAKE_PROJECT_VERSION@" diff --git a/configure b/configure deleted file mode 100755 index c5e3f3a..0000000 --- a/configure +++ /dev/null @@ -1,502 +0,0 @@ -#!/usr/bin/python - -import sys -if sys.version_info < (2, 7): - sys.path.insert(0, '.config') - -########################################################## -### Arg Parser ### -########################################################## - -import argparse, textwrap - -class ToggleAction(argparse.Action): - def __init__(self, **kw): - name = kw['option_strings'][0][2:] - if name.startswith('no-'): - name = name[3:] - kw['dest'] = name - kw['option_strings'] = [ '--no-' + name, '--' + name ] - kw['nargs'] = 0 - kw['metavar'] = None - super(ToggleAction, self).__init__(**kw) - - def __call__(self, parser, namespace, values, option_string=None): - if option_string and option_string.startswith('--no-'): - setattr(namespace, self.dest, False) - else: - setattr(namespace, self.dest, True) - - -class SmartHelpFmt(argparse.RawDescriptionHelpFormatter): - def _format_action(self, action): - if type(action) == ToggleAction: - opts = action.option_strings - action.option_strings = [ '--[no-]' + action.dest ] - parts = super(SmartHelpFmt, self)._format_action(action) - action.option_strings = opts - else: - parts = super(SmartHelpFmt, self)._format_action(action) - return parts - - def _format_usage(self, usage, actions, groups, prefix): - for g in groups: - print(g) - text = super(SmartHelpFmt, self)._format_usage(usage, - actions, groups, prefix) - # print "Usage", text - return text - - def format_help(self): - text = super(SmartHelpFmt, self).format_help() - return text - - -# Create help group with general '--help' option and with -# specific '--help-GROUP' for every argument group -class ArgParse(argparse.ArgumentParser): - def __init__(self, **kw): - self.help_names = [] - self.help_groups = {} - self.default_group = None - kw['add_help'] = False - kw['formatter_class'] = SmartHelpFmt - super(ArgParse, self).__init__(**kw) - self.add_argument_group('help', 'Help options', None) - self.add_argument("-h", "--help", help = "Print help and exit", - action = 'store_true', group = 'help') - - def add_argument_group(self, name, title=None, description=None, - default = None): - # print "add_argument_group: '%s'" % name, title, description, default - if name in self.help_groups: - raise BaseException("help group %s already exists" % name) - self.help_groups[name] = super(ArgParse, - self).add_argument_group(title, description) - if name != 'help' and len(name.split()) == 1: - self.add_argument("--help-" + name, group = 'help', - action = 'store_true', - help = "Help on " + title) - if default: - self.default_group = self.help_groups[name] - return self.help_groups[name] - - def add_argument(self, *args, **kw): - # print "add_argument:", args, kw - if 'group' in kw: - group = self.help_groups[kw['group']] - del kw['group'] - return group.add_argument(*args, **kw) - elif self.default_group: - return self.default_group.add_argument(*args, **kw) - else: - return self.add_argument(*args, **kw) - - - def format_help(self): - all = 'help' in self.help_names - if not all: - self.help_names = [ n[5:] for n in self.help_names] - - formatter = self._get_formatter() - - if all: - u = "%(prog)s " - for g in self._action_groups: - if g.title and g._group_actions: - u += '[_%s_] ' % g.title.replace(' ', '_') - u = textwrap.fill(u, - initial_indent = ' ' * 15, - subsequent_indent = ' ' * 13, - break_long_words = False).strip().replace('_', ' ') - - formatter.add_usage(u, None, []) - formatter.add_text(self.description) - - if all: - self.help_names = self.help_groups.keys() - - for name in self.help_names: - group = self.help_groups[name] - formatter.start_section(group.title) - formatter.add_text(group.description) - formatter.add_arguments(group._group_actions) - formatter.end_section() - - if all: - formatter.add_text(self.epilog) - - return formatter.format_help() - - def parse_args(self, args=None, namespace=None): - a = super(ArgParse, self).parse_args(args, namespace) - self.help_names = [ n for n in dir(a) if - (n == 'help' or n.startswith("help_")) and getattr(a, n) ] - if self.help_names: - self.print_help() - exit(0) - - return a - - -########################################################## -### log ### -########################################################## - -import subprocess as sp, re, sys, os, datetime -import traceback, tempfile, shutil -import logging -x = logging.getLogger('app') -def init_log(debug, verbose, *args): - for name in args: - x = logging.getLogger(name) - if debug: - f = logging.Formatter("%(name)s (%(funcName)s:%(lineno)d) " + - ":: %(message)s") - verbose = True - else: - f = logging.Formatter("%(message)s") - - h = logging.StreamHandler() - h.setFormatter(f) - x.addHandler(h) - if verbose: - x.setLevel(logging.DEBUG) - else: - x.setLevel(logging.INFO) - -p = ArgParse() - - -########################################################## -### Varables ### -########################################################## - -vars = {} - -def assign_cmd_vars(): - for v in args.vars: - x.debug("test %s", v) - m = re.match('^[A-Z_]+=.*', v) - if not m: - continue - l = v.split('=') - name = l[0] - value = l[1] - vars[name] = value - x.debug("name %s, value '%s'", name, value) - - -########################################################## -### Options ### -########################################################## -def my_check_output(*popenargs, **kwargs): - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - x.debug("exec: %s", cmd) - process = sp.Popen(stdout=sp.PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - output = output.decode("utf-8").strip() - if retcode: - raise sp.CalledProcessError(retcode, cmd, output=output) - return output - - -opts = {} -opt_order = [] -args = None -help_groups = {} -stack = [] -def opt(name): - global stack, opts, help_groups - - if name in stack: - raise BaseException("dep loop: second '" + name + "' in " - + str(stack + [name])) - stack.append(name) - x = opts[name] - if callable(x): - while callable(x): - x = x() - opts[name] = x - del stack[-1] - return x - - -def opt_group_new(name, desc, long_desc = None, default = None): - global help_groups - - if name in help_groups: - raise BaseException("Help group %s' already exists" % name) - help_groups[name] = p.add_argument_group(name, desc, long_desc, default) - -def opt_new(name, **kw): - global opts, opt_order - - if not re.match('^[a-zA-Z_][0-9a-zA-Z_]*$', name): - raise BaseException("Illegal opt name '%s'" % name) - if name in opts: - raise BaseException("opt %s' already exists" % name) - if 'help' in kw: - if not 'group' in kw: - help_groups['app'].add_argument("--" + name, **kw) - else: - group = kw['group'] - del kw['group'] - help_groups[group].add_argument("--" + name, **kw) - d = None - if 'default' in kw: - d = kw['default'] - if type(d) == str: - d = d.strip() - opts[name] = d - opt_order.append(name) - -# Creates set of variables from pkg-config output. -# First, it creates var for cflags and libs -# vname_cflags :: pkg-config pname --cflags -# vname_libs :: pkg-config pname --libs -# Then, for every var in vars -# vname_var :: pkg-config pname --variable=var -# -# Parameters: -# vname - prefix for variable names -# pname - pkg-config package name -# pvars - list of package variables, eg ['prefix', 'datadir'] -# pversion - version condition, eg '--atleast-version=2.14' -# required - true, for mandatory packages -def opt_new_from_pkg(vname, pname, pvars = [], pversion = "", required = True): - cmd = ['pkg-config', '--print-errors', pname] - try: - my_check_output(cmd + pversion.split(), stderr=sp.STDOUT) - except sp.CalledProcessError as e: - if required: - print(e.output) - print("This usually means that '" + pname + \ - "' development files are not installed") - exit(1) - else: - return - - opt_new(vname + '_libs', - default = my_check_output(cmd + ['--libs'])) - opt_new(vname + '_cflags', - default = my_check_output(cmd + ['--cflags'])) - opt_new(vname + '_version', - default = my_check_output(cmd + ['--modversion'])) - for v in pvars: - opt_new(vname + '_' + v, - default = my_check_output(cmd + ['--variable=' + v])) - -def pkg_exists(pname, extra = ""): - cmd = ['pkg-config', pname] + extra.split() - return sp.call(cmd) == 0 - - -def opt_set(name, value): - global opts - x.debug("set %s = '%s'", name, value) - opts[name] = value - -def assign_cmd_opts(): - global opts - x.debug("assign") - for k in [ y for y in dir(args) if y[:1] != '_' and y != 'vars' ]: - opts[k] = getattr(args, k) - x.debug("opts[%s] = '%s'", k, opts[k]) - -def write_config(): - now = datetime.datetime.now() - smake = "# Generated at %s \n# by command %s\n\n" % (now, sys.argv) - sc = "// Generated at %s \n// by command %s\n\n" % (now, sys.argv) - - for name in sorted(vars.keys()): - smake += "%s ?= %s\n" % (name, vars[name]) - smake += "\n" - - for name in opt_order: - v = opt(name) - # print name, type(v) - if not v: - continue - if type(v) == str: - v = v.replace('\n', '\\\n') - v = v.replace('"', '') - elif type(v) == bool: - v = int(v) - - smake += "%s := %s\n" % (name.upper(), str(v)) - if type(v) == str or type(v) == unicode: - v = '"' + v + '"' - sc += '#define %s %s\n' % (name.upper(), str(v)) - smake += "\n" - sc += "\n" - print('Created config.mk') - open('config.mk', 'w').write(smake) - print('Created config.h') - open('config.h', 'w').write(sc) - - -def write_repl(): - s = '' - for name in opt_order: - s += " '%s' : '%s',\n" % (name, str(opt(name))) - s = re.sub('#repl_dict#', s, open('.config/repl.py', 'r').read()) - open('repl.py', 'w').write(s) - os.chmod('repl.py', 0o755) - - -def init(): - pass - -def resolve(): - pass - -def report(): - pass - -########################################################## -### Self Install ### -########################################################## - -def mc_update(): - x.info("Downloading latest code") - - dtmp = tempfile.mkdtemp() - repo = 'https://github.com/aanatoly/miniconf.git' - - cmd = 'git clone -q %s %s' % (repo, dtmp) - my_check_output(cmd, shell = True) - - cmd = 'rsync -a %s/engine/ .' % dtmp - my_check_output(cmd, shell = True) - - shutil.rmtree(dtmp) - -def mc_makefiles(): - header_text = '## miniconf makefiles ## %d.%d ##\n' - header_re = '(?m)^## miniconf makefiles ## (\d+)\.(\d+) ##\n' - def makefile_needed(dirname): - x.debug("makefile_needed '%s'", dirname) - if dirname.split('/')[-1] == '.config': - x.debug("no - this dir is ignored") - return False - try: - h = open(os.path.join(dirname, 'Makefile'), 'r').readline() - except BaseException as e: - x.debug("yes - no read - %s", e) - return True - m = re.match(header_re, h) - if not m: - x.debug("yes - no header - %s", h) - return True - x.debug("no - header is ok") - return False - - x.info("Creating makefiles") - for dirname, dirs, filenames in os.walk('./'): - # remove starting './' - dirname = dirname[2:] - x.debug("dirname %s", dirname) - if dirname == '': - try: - dirs.remove('.config') - except: - pass - - for d in ['.git', '.svn', 'CVS']: - try: - dirs.remove(d) - except: - pass - x.debug("dirs: %s", dirs) - if not makefile_needed(dirname): - continue - level = len([ v for v in dirname.split('/') if v ]) - topdir = '/'.join(['..'] * level) - if not topdir: topdir = '.' - text = header_text % (1, 1) - text += '\nTOPDIR := ' + topdir + '\n\n' - if dirs: - text += 'SUBDIRS := ' + ' \\\n '.join(sorted(dirs)) + '\n\n' - - cfiles = sorted([ f for f in filenames if f.endswith('.c') ]) - cfiles = ' \\\n '.join(cfiles) - x.debug('cfiles %s', cfiles) - if cfiles: - name = os.path.basename(dirname) - text += '%s_src = %s\n' % (name, cfiles) - text += '%s_cflags = \n' % name - text += '%s_libs = \n' % name - text += '%s_type = \n' % name - text += '\n' - text += 'include $(TOPDIR)/.config/rules.mk\n' - - path = os.path.join(dirname, 'Makefile') - x.info("Create %s", path) - open(path, 'w').write(text) - - - print( "\nNow, you can test it. Run the commands:" ) - print( "./configure --help" ) - print( "./configure" ) - print( "make help" ) - print( "make V=1" ) - - -########################################################## -### main ### -########################################################## - -def main(): - global p, x, args - - opt_group_new('miniconf', 'miniconf installation options') - p.add_argument("--mc-update", group = 'miniconf', - help = "update or install configure scripts", - action = 'store_true') - p.add_argument("--mc-makefiles", group = 'miniconf', - help = "create Makefiles for a project", - action = 'store_true', default = False) - p.add_argument("--mc-debug", group = 'miniconf', - help = "enable debug output in miniconf", - action = 'store_true', default = False) - - opt_group_new('make', 'Makefile vars') - p.add_argument("vars", group = 'make', - help = "makefile vars, like 'CFLAGS=-02'", nargs='*') - - init() - args = p.parse_args() - init_log(args.mc_debug, 0, 'app') - mc = 0 - if args.mc_update: - mc_update() - mc = 1 - if args.mc_makefiles: - mc_makefiles() - mc = 1 - - if mc: - exit(0) - - assign_cmd_vars() - assign_cmd_opts() - resolve() - write_config() - write_repl() - report() - -if __name__ == "__main__": - try: - name = '.config/options.py' - code = compile(open(name, "r").read(), name, 'exec') - exec(code) - except: - x.info("Can't read .config/options.py") - pass - main() diff --git a/fbpanel-2009.ebuild b/contrib/fbpanel-2009.ebuild similarity index 100% rename from fbpanel-2009.ebuild rename to contrib/fbpanel-2009.ebuild diff --git a/fbpanel.ebuild b/contrib/fbpanel.ebuild similarity index 100% rename from fbpanel.ebuild rename to contrib/fbpanel.ebuild diff --git a/data/.gitignore b/data/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/data/Makefile b/data/Makefile deleted file mode 100644 index 6538c05..0000000 --- a/data/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := .. - -SUBDIRS := config \ - images \ - man - -include $(TOPDIR)/.config/rules.mk diff --git a/data/config/.gitignore b/data/config/.gitignore deleted file mode 100644 index 133e0b7..0000000 --- a/data/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -default -pager diff --git a/data/config/Makefile b/data/config/Makefile deleted file mode 100644 index 27ea677..0000000 --- a/data/config/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -TEXT = default pager -all : $(TEXT) -CLEANLIST += $(TEXT) - -install : - $Qinstall -d $(DESTDIR)$(DATADIR) - $Qinstall -m 644 $(TEXT) $(DESTDIR)$(DATADIR) - -include $(TOPDIR)/.config/rules.mk diff --git a/data/images/.gitignore b/data/images/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/data/images/Makefile b/data/images/Makefile deleted file mode 100644 index 92c2d17..0000000 --- a/data/images/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -IMAGES = \ -battery_0.png \ -battery_1.png \ -battery_2.png \ -battery_3.png \ -battery_4.png \ -battery_5.png \ -battery_6.png \ -battery_7.png \ -battery_8.png \ -battery_charging_0.png \ -battery_charging_1.png \ -battery_charging_2.png \ -battery_charging_3.png \ -battery_charging_4.png \ -battery_charging_5.png \ -battery_charging_6.png \ -battery_charging_7.png \ -battery_charging_8.png \ -battery_na.png \ -dclock_glyphs.png \ -default.xpm \ -gnome-session-halt.png \ -gnome-session-reboot.png \ -logo.png - - -install : - $Qinstall -d $(DESTDIR)$(DATADIR)/images - $Qinstall $(IMAGES) $(DESTDIR)$(DATADIR)/images - -include $(TOPDIR)/.config/rules.mk diff --git a/data/man/.gitignore b/data/man/.gitignore deleted file mode 100644 index b0e7d13..0000000 --- a/data/man/.gitignore +++ /dev/null @@ -1 +0,0 @@ -fbpanel.1 diff --git a/data/man/Makefile b/data/man/Makefile deleted file mode 100644 index 0591ea8..0000000 --- a/data/man/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -TEXT = fbpanel.1 -all : $(TEXT) -CLEANLIST += $(TEXT) - -install : - $Qinstall -d $(DESTDIR)$(MANDIR) - $Qinstall -m 644 $(TEXT) $(DESTDIR)$(MANDIR) - -include $(TOPDIR)/.config/rules.mk diff --git a/exec/.gitignore b/exec/.gitignore deleted file mode 100644 index 4b7430e..0000000 --- a/exec/.gitignore +++ /dev/null @@ -1 +0,0 @@ -make_profile diff --git a/exec/Makefile b/exec/Makefile deleted file mode 100644 index a13f06c..0000000 --- a/exec/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := .. - -TEXT = make_profile xlogout -all : $(TEXT) -CLEANLIST += make_profile - -install : - $Qinstall -d $(DESTDIR)$(LIBEXECDIR) - $Qinstall -m 755 $(TEXT) $(DESTDIR)$(LIBEXECDIR) - -include $(TOPDIR)/.config/rules.mk diff --git a/panel/.gitignore b/panel/.gitignore deleted file mode 100644 index 7742cf7..0000000 --- a/panel/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -bg.o -bg.d -ev.o -ev.d -gconf.o -gconf.d -gconf_panel.o -gconf_panel.d -gconf_plugins.o -gconf_plugins.d -gtkbar.o -gtkbar.d -gtkbgbox.o -gtkbgbox.d -misc.o -misc.d -panel.o -panel.d -plugin.o -plugin.d -run.o -run.d -xconf.o -xconf.d -fbpanel diff --git a/panel/Makefile b/panel/Makefile deleted file mode 100644 index f3dcc8f..0000000 --- a/panel/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := .. - -fbpanel_src = bg.c \ - ev.c \ - gconf.c \ - gconf_panel.c \ - gconf_plugins.c \ - gtkbar.c \ - gtkbgbox.c \ - misc.c \ - panel.c \ - plugin.c \ - run.c \ - xconf.c -fbpanel_cflags = $(GTK2_CFLAGS) $(GMODULE2_CFLAGS) $(X11_CFLAGS) -fbpanel_libs = $(GTK2_LIBS) $(GMODULE2_LIBS) $(X11_LIBS) -lm -fbpanel_type = bin - -include $(TOPDIR)/.config/rules.mk diff --git a/panel/gconf_panel.c b/panel/gconf_panel.c index 25d55cc..bec0e80 100644 --- a/panel/gconf_panel.c +++ b/panel/gconf_panel.c @@ -233,7 +233,7 @@ mk_geom_block(xconf *xc) w = gconf_edit_enum(geom_block, xconf_get(xc, "allign"), allign_enum); - gconf_block_add(geom_block, gtk_label_new(_("Allignment")), TRUE); + gconf_block_add(geom_block, gtk_label_new(_("Alignment")), TRUE); gconf_block_add(geom_block, w, FALSE); allign_opt = w; diff --git a/panel/gtkbgbox.c b/panel/gtkbgbox.c index 29a24cc..e6528c0 100644 --- a/panel/gtkbgbox.c +++ b/panel/gtkbgbox.c @@ -47,9 +47,7 @@ typedef struct { gulong sid; } GtkBgboxPrivate; - - -#define GTK_BGBOX_GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_BGBOX, GtkBgboxPrivate) +G_DEFINE_TYPE_WITH_CODE(GtkBgbox, gtk_bgbox, GTK_TYPE_BIN, G_ADD_PRIVATE(GtkBgbox)) static void gtk_bgbox_class_init (GtkBgboxClass *klass); static void gtk_bgbox_init (GtkBgbox *bgbox); @@ -71,33 +69,6 @@ static void gtk_bgbox_bg_changed(FbBg *bg, GtkWidget *widget); static GtkBinClass *parent_class = NULL; -GType -gtk_bgbox_get_type (void) -{ - static GType bgbox_type = 0; - - if (!bgbox_type) - { - static const GTypeInfo bgbox_info = - { - sizeof (GtkBgboxClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gtk_bgbox_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GtkBgbox), - 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_bgbox_init, - }; - - bgbox_type = g_type_register_static (GTK_TYPE_BIN, "GtkBgbox", - &bgbox_info, 0); - } - - return bgbox_type; -} - static void gtk_bgbox_class_init (GtkBgboxClass *class) { @@ -111,11 +82,8 @@ gtk_bgbox_class_init (GtkBgboxClass *class) widget_class->size_allocate = gtk_bgbox_size_allocate; widget_class->style_set = gtk_bgbox_style_set; widget_class->configure_event = gtk_bgbox_configure_event; - //widget_class->destroy_event = gtk_bgbox_destroy_event; - //widget_class->delete_event = gtk_bgbox_delete_event; object_class->finalize = gtk_bgbox_finalize; - g_type_class_add_private (class, sizeof (GtkBgboxPrivate)); } static void @@ -126,7 +94,7 @@ gtk_bgbox_init (GtkBgbox *bgbox) ENTER; GTK_WIDGET_UNSET_FLAGS (bgbox, GTK_NO_WINDOW); - priv = GTK_BGBOX_GET_PRIVATE (bgbox); + priv = gtk_bgbox_get_instance_private(bgbox); priv->bg_type = BG_NONE; priv->sid = 0; RET(); @@ -145,7 +113,7 @@ gtk_bgbox_finalize (GObject *object) GtkBgboxPrivate *priv; ENTER; - priv = GTK_BGBOX_GET_PRIVATE(GTK_WIDGET(object)); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(object)); if (priv->pixmap) { g_object_unref(priv->pixmap); priv->pixmap = NULL; @@ -169,7 +137,6 @@ gtk_bgbox_event_filter(GdkXEvent *xevent, GdkEvent *event, GtkWidget *widget) ENTER; if (ev->type == ConfigureNotify) { gtk_widget_queue_draw(widget); - //gtk_bgbox_style_set(widget, NULL); DBG("ConfigureNotify %d %d %d %d\n", ev->xconfigure.x, ev->xconfigure.y, @@ -207,7 +174,7 @@ gtk_bgbox_realize (GtkWidget *widget) | GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK; - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); @@ -232,7 +199,7 @@ gtk_bgbox_style_set (GtkWidget *widget, GtkStyle *previous_style) GtkBgboxPrivate *priv; ENTER; - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget)) { gtk_bgbox_set_background(widget, priv->bg_type, priv->tintcolor, priv->alpha); } @@ -297,7 +264,7 @@ gtk_bgbox_size_allocate (GtkWidget *widget, GtkAllocation *wa) if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget) && !same_alloc) { - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); DBG("move resize pos=%d,%d geom=%dx%d\n", wa->x, wa->y, wa->width, wa->height); gdk_window_move_resize (widget->window, wa->x, wa->y, wa->width, wa->height); @@ -316,7 +283,7 @@ gtk_bgbox_bg_changed(FbBg *bg, GtkWidget *widget) GtkBgboxPrivate *priv; ENTER; - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_NO_WINDOW (widget)) { gtk_bgbox_set_background(widget, priv->bg_type, priv->tintcolor, priv->alpha); } @@ -332,7 +299,7 @@ gtk_bgbox_set_background(GtkWidget *widget, int bg_type, guint32 tintcolor, gint if (!(GTK_IS_BGBOX (widget))) RET(); - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); DBG("widget=%p bg_type old:%d new:%d\n", widget, priv->bg_type, bg_type); if (priv->pixmap) { g_object_unref(priv->pixmap); @@ -373,12 +340,11 @@ gtk_bgbox_set_background(GtkWidget *widget, int bg_type, guint32 tintcolor, gint static void gtk_bgbox_set_bg_root(GtkWidget *widget, GtkBgboxPrivate *priv) { - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); ENTER; priv->pixmap = fb_bg_get_xroot_pix_for_win(priv->bg, widget); if (!priv->pixmap || priv->pixmap == GDK_NO_BG) { - //priv->bg_type = BG_NONE; priv->pixmap = NULL; gtk_style_set_background(widget->style, widget->window, widget->state); gtk_widget_queue_draw_area(widget, 0, 0, @@ -396,7 +362,7 @@ gtk_bgbox_set_bg_root(GtkWidget *widget, GtkBgboxPrivate *priv) static void gtk_bgbox_set_bg_inherit(GtkWidget *widget, GtkBgboxPrivate *priv) { - priv = GTK_BGBOX_GET_PRIVATE (widget); + priv = gtk_bgbox_get_instance_private(GTK_BGBOX(widget)); ENTER; gdk_window_set_back_pixmap(widget->window, NULL, TRUE); diff --git a/panel/gtkbgbox.h b/panel/gtkbgbox.h index 3bd815d..5b72963 100644 --- a/panel/gtkbgbox.h +++ b/panel/gtkbgbox.h @@ -61,7 +61,7 @@ enum { BG_NONE, BG_STYLE, BG_ROOT, BG_INHERIT, BG_LAST }; GType gtk_bgbox_get_type (void) G_GNUC_CONST; GtkWidget* gtk_bgbox_new (void); -void gtk_bgbox_set_background (GtkWidget *widget, int bg_type, guint32 tintcolor, gint alpha); +extern void gtk_bgbox_set_background (GtkWidget *widget, int bg_type, guint32 tintcolor, gint alpha); #ifdef __cplusplus diff --git a/panel/misc.c b/panel/misc.c index 3b5ae94..5a01490 100644 --- a/panel/misc.c +++ b/panel/misc.c @@ -295,7 +295,7 @@ get_utf8_property_list(Window win, Atom atom, int *count) if (val[nitems-1]) { result = nitems - (s - val); DBG("val does not ends by 0, moving last %d bytes\n", result); - g_memmove(s - 1, s, result); + memmove(s - 1, s, result); val[nitems-1] = 0; DBG("s=%s\n", s -1); retval[i] = g_strdup(s - 1); @@ -569,22 +569,41 @@ calculate_width(int scrw, int wtype, int allign, int xmargin, void calculate_position(panel *np) { + int positionSet = 0; int sswidth, ssheight, minx, miny; ENTER; - if (0) { - //if (np->curdesk < np->wa_len/4) { - minx = np->workarea[np->curdesk*4 + 0]; - miny = np->workarea[np->curdesk*4 + 1]; - sswidth = np->workarea[np->curdesk*4 + 2]; - ssheight = np->workarea[np->curdesk*4 + 3]; - } else { + + /* If a Xinerama head was specified on the command line, then + * calculate the location based on that. Otherwise, just use the + * screen dimensions. */ + if(np->xineramaHead != FBPANEL_INVALID_XINERAMA_HEAD) { + GdkScreen *screen = gdk_screen_get_default(); + int nDisplay = gdk_screen_get_n_monitors(screen); + GdkRectangle rect; + + if(np->xineramaHead < nDisplay) { + gdk_screen_get_monitor_geometry(screen, np->xineramaHead, &rect); + minx = rect.x; + miny = rect.y; + sswidth = rect.width; + ssheight = rect.height; + positionSet = 1; + } + } + + if (!positionSet) { minx = miny = 0; sswidth = gdk_screen_width(); ssheight = gdk_screen_height(); } + np->screenRect.x = minx; + np->screenRect.y = miny; + np->screenRect.width = sswidth; + np->screenRect.height = ssheight; + if (np->edge == EDGE_TOP || np->edge == EDGE_BOTTOM) { np->aw = np->width; np->ax = minx; @@ -697,7 +716,7 @@ gchar * gdk_color_to_RRGGBB(GdkColor *color) { static gchar str[10]; // #RRGGBB + \0 - g_sprintf(str, "#%02x%02x%02x", + g_snprintf(str, sizeof(str), "#%02x%02x%02x", color->red >> 8, color->green >> 8, color->blue >> 8); return str; } @@ -705,50 +724,60 @@ gdk_color_to_RRGGBB(GdkColor *color) void menu_pos(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, GtkWidget *widget) { - int w, h; + GdkRectangle menuRect; + GdkRectangle validRect = the_panel->screenRect; ENTER; - *push_in = TRUE; - if (!widget) { - gdk_display_get_pointer(gdk_display_get_default(), NULL, x, y, NULL); - DBG("mouse pos: x %d, y %d\n", *x, *y); - DBG("menu pos: x %d, y %d\n", *x, *y); - RET(); + + /* "validRect" is a rectangle of the valid location to place the menu. */ + if(the_panel->orientation == GTK_ORIENTATION_HORIZONTAL) { + validRect.height -= the_panel->ah; + if(the_panel->edge == EDGE_TOP) { + validRect.y += the_panel->ah; + } + } else { + validRect.width -= the_panel->aw; + if(the_panel->edge == EDGE_LEFT) { + validRect.x += the_panel->aw; + } } - DBG("widget: x %d, y %d, w %d, h %d\n", - widget->allocation.x, - widget->allocation.y, - widget->allocation.width, - widget->allocation.height); - gdk_window_get_origin(widget->window, x, y); - DBG("window pos: x %d, y %d\n", *x, *y); - DBG("edge: %s\n", num2str(edge_enum, the_panel->edge, "xz")); - if (the_panel->edge == EDGE_TOP) { - *y += widget->allocation.height; - *y += widget->allocation.y; - *x += widget->allocation.x; - } else if (the_panel->edge == EDGE_LEFT) { - *x += widget->allocation.width; - *y += widget->allocation.y; - *x += widget->allocation.x; + + /* Calculate a requested location based on the widget/mouse location, + * relative to the root window. */ + if (widget) { + gdk_window_get_origin(widget->window, &menuRect.x, &menuRect.y); + menuRect.x += widget->allocation.x; + menuRect.y += widget->allocation.y; } else { - w = GTK_WIDGET(menu)->requisition.width; - h = GTK_WIDGET(menu)->requisition.height; - if (the_panel->edge == EDGE_BOTTOM) { - *x += widget->allocation.x; - *y += widget->allocation.y; - *y -= h; - if (*y < 0) - *y = 0; - } else if (the_panel->edge == EDGE_RIGHT) { - *y += widget->allocation.y; - *x -= w; - *x -= widget->allocation.x; - if (*x < 0) - *x = 0; - } + gdk_display_get_pointer(gdk_display_get_default(), NULL, + &menuRect.x, &menuRect.y, NULL); + menuRect.x -= 20; + menuRect.y -= 20; } - DBG("menu pos: x %d, y %d\n", *x, *y); + + menuRect.width = GTK_WIDGET(menu)->requisition.width; + menuRect.height = GTK_WIDGET(menu)->requisition.height; + + /* If "menuRect" does not fall within "validRect", then move "menuRect" + * to fit. */ + if(menuRect.x + menuRect.width > validRect.x + validRect.width) { + menuRect.x = validRect.x + validRect.width - menuRect.width; + } + if(menuRect.x < validRect.x) { + menuRect.x = validRect.x; + } + if(menuRect.y + menuRect.height > validRect.y + validRect.height) { + menuRect.y = validRect.y + validRect.height - menuRect.height; + } + if(menuRect.y < validRect.y) { + menuRect.y = validRect.y; + } + + *x = menuRect.x; + *y = menuRect.y; + + DBG("w-h %d %d\n", menuRect.width, menuRect.height); + *push_in = TRUE; RET(); } @@ -816,6 +845,10 @@ fb_pixbuf_make_back_image(GdkPixbuf *front, gulong hicolor) int i; ENTER; + if(!front) + { + RET(front); + } back = gdk_pixbuf_add_alpha(front, FALSE, 0, 0, 0); if (!back) { g_object_ref(G_OBJECT(front)); @@ -846,6 +879,10 @@ fb_pixbuf_make_press_image(GdkPixbuf *front) int w, h; ENTER; + if(!front) + { + RET(front); + } w = gdk_pixbuf_get_width(front) - 2 * PRESS_GAP; h = gdk_pixbuf_get_height(front) - 2 * PRESS_GAP; press = gdk_pixbuf_copy(front); diff --git a/panel/misc.h b/panel/misc.h index 3e31114..4e0ac63 100644 --- a/panel/misc.h +++ b/panel/misc.h @@ -13,9 +13,9 @@ int str2num(xconf_enum *p, gchar *str, int defval); gchar *num2str(xconf_enum *p, int num, gchar *defval); -void Xclimsg(Window win, long type, long l0, long l1, long l2, long l3, long l4); +extern void Xclimsg(Window win, long type, long l0, long l1, long l2, long l3, long l4); void Xclimsgwm(Window win, Atom type, Atom arg); -void *get_xaproperty (Window win, Atom prop, Atom type, int *nitems); +extern void *get_xaproperty (Window win, Atom prop, Atom type, int *nitems); char *get_textproperty(Window win, Atom prop); void *get_utf8_property(Window win, Atom atom); char **get_utf8_property_list(Window win, Atom atom, int *count); @@ -24,10 +24,10 @@ void fb_init(void); void fb_free(void); //Window Select_Window(Display *dpy); guint get_net_number_of_desktops(); -guint get_net_current_desktop (); -guint get_net_wm_desktop(Window win); -void get_net_wm_state(Window win, net_wm_state *nws); -void get_net_wm_window_type(Window win, net_wm_window_type *nwwt); +extern guint get_net_current_desktop (); +extern guint get_net_wm_desktop(Window win); +extern void get_net_wm_state(Window win, net_wm_state *nws); +extern void get_net_wm_window_type(Window win, net_wm_window_type *nwwt); void calculate_position(panel *np); gchar *expand_tilda(gchar *file); diff --git a/panel/panel.c b/panel/panel.c index 811be95..1d60cf0 100644 --- a/panel/panel.c +++ b/panel/panel.c @@ -28,6 +28,7 @@ guint hpid; // hide panel thread id FbEv *fbev; gint force_quit = 0; int config; +int xineramaHead = FBPANEL_INVALID_XINERAMA_HEAD; //#define DEBUGPRN #include "dbg.h" @@ -895,6 +896,15 @@ do_argv(int argc, char *argv[]) } else { profile = g_strdup(argv[i]); } + } else if (!strcmp(argv[i], "--xineramaHead") || + !strcmp(argv[i], "-x")) { + i++; + if(i == argc) { + ERR("fbpanel: xinerama head not specified\n"); + usage(); + exit(1); + } + xineramaHead = atoi(argv[i]); } else { printf("fbpanel: unknown option - %s\n", argv[i]); usage(); @@ -958,6 +968,7 @@ main(int argc, char *argv[]) do { the_panel = p = g_new0(panel, 1); + p->xineramaHead = xineramaHead; p->xc = xconf_new_from_file(profile_file, profile); if (!p->xc) exit(1); diff --git a/panel/panel.h b/panel/panel.h index c07bc9f..03ccdb4 100644 --- a/panel/panel.h +++ b/panel/panel.h @@ -57,6 +57,9 @@ typedef struct _panel int round_corners_radius; int max_elem_height; + int xineramaHead; + GdkRectangle screenRect; + gint self_destroy; gint setdocktype; gint setstrut; @@ -190,4 +193,6 @@ gchar *panel_get_profile_file(void); void ah_start(panel *p); void ah_stop(panel *p); +#define FBPANEL_INVALID_XINERAMA_HEAD (-1) + #endif diff --git a/panel/plugin.h b/panel/plugin.h index 14ff038..cb951de 100644 --- a/panel/plugin.h +++ b/panel/plugin.h @@ -9,7 +9,7 @@ #include #include "panel.h" -struct _plugin_instance *stam; +struct _plugin_instance; typedef struct { /* common */ @@ -53,8 +53,8 @@ int plugin_start(plugin_instance *this); void plugin_stop(plugin_instance *this); GtkWidget *default_plugin_instance_edit_config(plugin_instance *pl); -void class_register(plugin_class *p); -void class_unregister(plugin_class *p); +extern void class_register(plugin_class *p); +extern void class_unregister(plugin_class *p); #ifdef PLUGIN static plugin_class *class_ptr; diff --git a/plugins/.gitignore b/plugins/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/Makefile b/plugins/Makefile deleted file mode 100644 index 2990136..0000000 --- a/plugins/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := .. - -SUBDIRS := battery \ - chart \ - cpu \ - dclock \ - deskno \ - deskno2 \ - genmon \ - icons \ - image \ - launchbar \ - mem \ - mem2 \ - menu \ - meter \ - net \ - pager \ - separator \ - space \ - systray \ - taskbar \ - tclock \ - volume \ - wincmd \ - user - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/battery/.gitignore b/plugins/battery/.gitignore deleted file mode 100644 index 45a985d..0000000 --- a/plugins/battery/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -battery.o -battery.d -power_supply.o -power_supply.d -libbattery.so diff --git a/plugins/battery/Makefile b/plugins/battery/Makefile deleted file mode 100644 index 6967680..0000000 --- a/plugins/battery/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -battery_src = battery.c power_supply.c -battery_cflags = -DPLUGIN $(GTK2_CFLAGS) -battery_libs = $(GTK2_LIBS) -battery_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/battery/Makefile-test b/plugins/battery/Makefile-test deleted file mode 100644 index 3dc7095..0000000 --- a/plugins/battery/Makefile-test +++ /dev/null @@ -1,18 +0,0 @@ -# -*- mode: Makefile -*- -# Time-stamp: < Makefile-test (2015-12-04 19:02) > - -CC = gcc -Wall -g -O0 `pkg-config --cflags --libs glib-2.0` - -all: main - -clean: - rm -rf *.o main - -main: main.c power_supply.o - $(CC) main.c power_supply.o -o $@ - -power_supply.o: power_supply.h power_supply.c - $(CC) -c power_supply.c -o $@ - -valgrind: main - G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=yes ./main diff --git a/plugins/battery/battery.c b/plugins/battery/battery.c index ab736e3..93d12d9 100644 --- a/plugins/battery/battery.c +++ b/plugins/battery/battery.c @@ -52,7 +52,7 @@ static gchar *batt_na[] = { }; #if defined __linux__ -#include "os_linux.c" +#include "os_linux.c.inc" #else static void diff --git a/plugins/battery/os_linux.c b/plugins/battery/os_linux.c.inc similarity index 100% rename from plugins/battery/os_linux.c rename to plugins/battery/os_linux.c.inc diff --git a/plugins/battery/power_supply.c b/plugins/battery/power_supply.c index ab3f359..846a5e8 100644 --- a/plugins/battery/power_supply.c +++ b/plugins/battery/power_supply.c @@ -154,7 +154,7 @@ bat_new(gchar* path) tmp->path = path; tmp->name = NULL; tmp->status = NULL; - tmp->capacity = -1.0d; + tmp->capacity = -1; return tmp; } @@ -206,12 +206,12 @@ bat_parse(bat* bat) bat->capacity = g_ascii_strtod(tmp_value, NULL); } else { // for older kernels tmp_value = (gchar*) g_hash_table_lookup(hash, SYS_ACPI_UEVENT_BAT_ENERGY_NOW_KEY); - gdouble tmp = -1.0d; + gdouble tmp = -1; if (tmp_value != NULL) { // ac off tmp = g_ascii_strtod(tmp_value, NULL); tmp_value = (gchar*) g_hash_table_lookup(hash, SYS_ACPI_UEVENT_BAT_ENERGY_FULL_KEY); - if (tmp_value != NULL && tmp > 0.0d) { - tmp = tmp / g_ascii_strtod(tmp_value, NULL) * 100.0d; + if (tmp_value != NULL && tmp > 0) { + tmp = tmp / g_ascii_strtod(tmp_value, NULL) * 100; bat->capacity = tmp; } } else { @@ -219,8 +219,8 @@ bat_parse(bat* bat) if (tmp_value != NULL) { // ac on tmp = g_ascii_strtod(tmp_value, NULL); tmp_value = (gchar*) g_hash_table_lookup(hash, SYS_ACPI_UEVENT_BAT_CHARGE_FULL_KEY); - if (tmp_value != NULL && tmp > 0.0d) { - tmp = tmp / g_ascii_strtod(tmp_value, NULL) * 100.0d; + if (tmp_value != NULL && tmp > 0) { + tmp = tmp / g_ascii_strtod(tmp_value, NULL) * 100; bat->capacity = tmp; } } @@ -327,7 +327,7 @@ power_supply_is_ac_online(power_supply* ps) extern gdouble power_supply_get_bat_capacity(power_supply* ps) { - gdouble total_bat_capacity = 0.0d; + gdouble total_bat_capacity = 0; guint bat_count = 0; GSequenceIter* it; bat* battery; @@ -335,7 +335,7 @@ power_supply_get_bat_capacity(power_supply* ps) it = g_sequence_get_begin_iter(ps->bat_list); while (!g_sequence_iter_is_end(it)) { battery = (bat*) g_sequence_get(it); - if (battery->capacity > 0.0d) { + if (battery->capacity > 0) { total_bat_capacity = total_bat_capacity + battery->capacity; } bat_count++; diff --git a/plugins/batterytext/batterytext.c b/plugins/batterytext/batterytext.c new file mode 100644 index 0000000..15613e6 --- /dev/null +++ b/plugins/batterytext/batterytext.c @@ -0,0 +1,169 @@ +/* batterytext_priv.c -- Generic monitor plugin for fbpanel + * + * Copyright (C) 2017 Fred Stober + * + * This plugin 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; version 2 dated June, 1991. + * + * It 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. + */ + +#include +#include +#include +#include + +#include "panel.h" +#include "misc.h" +#include "plugin.h" + +//#define DEBUG +#include "dbg.h" + +typedef struct { + plugin_instance plugin; + int design; + int time; + char *textsize; + char *battery; + int timer; + GtkWidget *main; +} batterytext_priv; + +static float +read_bat_value(const char *dn, const char *fn) +{ + FILE *fp; + float value = -1; + char value_path[256]; + g_snprintf(value_path, sizeof(value_path), "%s/%s", dn, fn); + fp = fopen(value_path, "r"); + if (fp != NULL) { + if (fscanf(fp, "%f", &value) != 1) + value = -1; + fclose(fp); + } + return value; +} + +static int +text_update(batterytext_priv *gm) +{ + FILE *fp_status; + char battery_status[256]; + char *markup; + char *tooltip; + char buffer[256]; + float energy_full_design = -1; + float energy_full = -1; + float energy_now = -1; + float power_now = -1; + int discharging = 0; + float charge_ratio = 0; + int charge_time = 0; + + ENTER; + energy_full_design = read_bat_value(gm->battery, "energy_full_design"); + energy_full = read_bat_value(gm->battery, "energy_full"); + energy_now = read_bat_value(gm->battery, "energy_now"); + power_now = read_bat_value(gm->battery, "power_now"); + + snprintf(battery_status, sizeof(battery_status), "%s/status", gm->battery); + fp_status = fopen(battery_status, "r"); + if (fp_status != NULL) { + while ((fgets(buffer, sizeof(buffer), fp_status)) != NULL) { + if (strstr(buffer, "Discharging") != NULL) + discharging = 1; + } + fclose(fp_status); + } + + if ((energy_full_design >= 0) && (energy_now >= 0)) { + if (gm->design) + charge_ratio = 100 * energy_now / energy_full_design; + else + charge_ratio = 100 * energy_now / energy_full; + if (discharging) + { + markup = g_markup_printf_escaped("%.2f-", + gm->textsize, charge_ratio); + charge_time = (int)(energy_now / power_now * 3600); + } + else + { + markup = g_markup_printf_escaped("%.2f+", + gm->textsize, charge_ratio); + charge_time = (int)((energy_full - energy_now) / power_now * 3600); + } + tooltip = g_markup_printf_escaped("%02d:%02d:%02d", + charge_time / 3600, (charge_time / 60) % 60, charge_time % 60); + gtk_label_set_markup (GTK_LABEL(gm->main), markup); + g_free(markup); + gtk_widget_set_tooltip_markup (gm->main, tooltip); + g_free(tooltip); + } + else + { + gtk_label_set_markup (GTK_LABEL(gm->main), "N/A"); + gtk_widget_set_tooltip_markup (gm->main, "N/A"); + } + RET(TRUE); +} + +static void +batterytext_destructor(plugin_instance *p) +{ + batterytext_priv *gm = (batterytext_priv *) p; + + ENTER; + if (gm->timer) { + g_source_remove(gm->timer); + } + RET(); +} + +static int +batterytext_constructor(plugin_instance *p) +{ + batterytext_priv *gm; + + ENTER; + gm = (batterytext_priv *) p; + gm->design = False; + gm->time = 500; + gm->textsize = "medium"; + gm->battery = "/sys/class/power_supply/BAT0"; + + XCG(p->xc, "DesignCapacity", &gm->design, enum, bool_enum); + XCG(p->xc, "PollingTimeMs", &gm->time, int); + XCG(p->xc, "TextSize", &gm->textsize, str); + XCG(p->xc, "BatteryPath", &gm->battery, str); + + gm->main = gtk_label_new(NULL); + text_update(gm); + gtk_container_set_border_width (GTK_CONTAINER (p->pwid), 1); + gtk_container_add(GTK_CONTAINER(p->pwid), gm->main); + gtk_widget_show_all(p->pwid); + gm->timer = g_timeout_add((guint) gm->time, + (GSourceFunc) text_update, (gpointer) gm); + + RET(1); +} + + +static plugin_class class = { + .count = 0, + .type = "batterytext", + .name = "Generic Monitor", + .version = "0.1", + .description = "Display battery usage in text form", + .priv_size = sizeof(batterytext_priv), + + .constructor = batterytext_constructor, + .destructor = batterytext_destructor, +}; +static plugin_class *class_ptr = (plugin_class *) &class; diff --git a/plugins/chart/.gitignore b/plugins/chart/.gitignore deleted file mode 100644 index 829128a..0000000 --- a/plugins/chart/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -chart.o -chart.d -libchart.so diff --git a/plugins/chart/Makefile b/plugins/chart/Makefile deleted file mode 100644 index cd6849f..0000000 --- a/plugins/chart/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -chart_src = chart.c -chart_cflags = -DPLUGIN $(GTK2_CFLAGS) -chart_libs = $(GTK2_LIBS) -chart_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/cpu/.gitignore b/plugins/cpu/.gitignore deleted file mode 100644 index b68da54..0000000 --- a/plugins/cpu/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -cpu.o -cpu.d -libcpu.so diff --git a/plugins/cpu/Makefile b/plugins/cpu/Makefile deleted file mode 100644 index 9df0944..0000000 --- a/plugins/cpu/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -cpu_src = cpu.c -cpu_cflags = -DPLUGIN $(GTK2_CFLAGS) -cpu_libs = $(GTK2_LIBS) -cpu_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/cpu/cpu.c b/plugins/cpu/cpu.c index fef3ca8..3281936 100644 --- a/plugins/cpu/cpu.c +++ b/plugins/cpu/cpu.c @@ -46,9 +46,11 @@ cpu_get_load_real(struct cpu_stat *cpu) stat = fopen("/proc/stat", "r"); if(!stat) return -1; - if (fscanf(stat, "cpu %lu %lu %lu %lu %lu", &cpu->u, &cpu->n, &cpu->s, - &cpu->i, &cpu->w)); + + (void)fscanf(stat, "cpu %lu %lu %lu %lu %lu", &cpu->u, &cpu->n, &cpu->s, + &cpu->i, &cpu->w); fclose(stat); + return 0; } #elif defined __FreeBSD__ diff --git a/plugins/dclock/.gitignore b/plugins/dclock/.gitignore deleted file mode 100644 index b1331e4..0000000 --- a/plugins/dclock/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -dclock.o -dclock.d -libdclock.so diff --git a/plugins/dclock/Makefile b/plugins/dclock/Makefile deleted file mode 100644 index 09f4f9f..0000000 --- a/plugins/dclock/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -dclock_src = dclock.c -dclock_cflags = -DPLUGIN $(GTK2_CFLAGS) -dclock_libs = $(GTK2_LIBS) -dclock_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/deskno/.gitignore b/plugins/deskno/.gitignore deleted file mode 100644 index c1ad8ce..0000000 --- a/plugins/deskno/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -deskno.o -deskno.d -libdeskno.so diff --git a/plugins/deskno/Makefile b/plugins/deskno/Makefile deleted file mode 100644 index badd30c..0000000 --- a/plugins/deskno/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -deskno_src = deskno.c -deskno_cflags = -DPLUGIN $(GTK2_CFLAGS) -deskno_libs = $(GTK2_LIBS) -deskno_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/deskno/deskno.c b/plugins/deskno/deskno.c index 3d4a715..e7fb79d 100644 --- a/plugins/deskno/deskno.c +++ b/plugins/deskno/deskno.c @@ -57,7 +57,7 @@ name_update(GtkWidget *widget, deskno_priv *dc) ENTER; dc->deskno = get_net_current_desktop(); - sprintf(buffer, "%d", dc->deskno + 1); + snprintf(buffer, sizeof(buffer), "%d", dc->deskno + 1); gtk_label_set_markup(GTK_LABEL(dc->namew), buffer); RET(TRUE); } diff --git a/plugins/deskno2/#Makefile# b/plugins/deskno2/#Makefile# deleted file mode 100644 index 6c497db..0000000 --- a/plugins/deskno2/#Makefile# +++ /dev/null @@ -1,6 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/deskno2/.gitignore b/plugins/deskno2/.gitignore deleted file mode 100644 index 63dbedf..0000000 --- a/plugins/deskno2/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -deskno2.o -deskno2.d -libdeskno2.so diff --git a/plugins/deskno2/Makefile b/plugins/deskno2/Makefile deleted file mode 100644 index 9fb05eb..0000000 --- a/plugins/deskno2/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -deskno2_src = deskno2.c -deskno2_cflags = -DPLUGIN $(GTK2_CFLAGS) -deskno2_libs = $(GTK2_LIBS) -deskno2_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/deskno2/deskno2.c b/plugins/deskno2/deskno2.c index 1ea39c8..3d7c1f9 100644 --- a/plugins/deskno2/deskno2.c +++ b/plugins/deskno2/deskno2.c @@ -25,7 +25,7 @@ typedef struct { static void clicked(GtkWidget *widget, deskno_priv *dc) { - if (system("xfce-setting-show workspaces")); + (void)system("xfce-setting-show workspaces"); } static void diff --git a/plugins/genmon/.gitignore b/plugins/genmon/.gitignore deleted file mode 100644 index 0ed635a..0000000 --- a/plugins/genmon/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -genmon.o -genmon.d -libgenmon.so diff --git a/plugins/genmon/Makefile b/plugins/genmon/Makefile deleted file mode 100644 index 29bf002..0000000 --- a/plugins/genmon/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -genmon_src = genmon.c -genmon_cflags = -DPLUGIN $(GTK2_CFLAGS) -genmon_libs = $(GTK2_LIBS) -genmon_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/genmon/genmon.c b/plugins/genmon/genmon.c index 274ed6b..258cfd3 100644 --- a/plugins/genmon/genmon.c +++ b/plugins/genmon/genmon.c @@ -47,7 +47,7 @@ text_update(genmon_priv *gm) ENTER; fp = popen(gm->command, "r"); - if (fgets(text, sizeof(text), fp)); + (void)fgets(text, sizeof(text), fp); pclose(fp); len = strlen(text) - 1; if (len >= 0) { diff --git a/plugins/icons/.gitignore b/plugins/icons/.gitignore deleted file mode 100644 index e61efdd..0000000 --- a/plugins/icons/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -icons.o -icons.d -libicons.so diff --git a/plugins/icons/Makefile b/plugins/icons/Makefile deleted file mode 100644 index b7a7c79..0000000 --- a/plugins/icons/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -icons_src = icons.c -icons_cflags = -DPLUGIN $(GTK2_CFLAGS) -icons_libs = $(GTK2_LIBS) -icons_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/image/.gitignore b/plugins/image/.gitignore deleted file mode 100644 index a9f34b9..0000000 --- a/plugins/image/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -image.o -image.d -libimage.so diff --git a/plugins/image/Makefile b/plugins/image/Makefile deleted file mode 100644 index 8407136..0000000 --- a/plugins/image/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -image_src = image.c -image_cflags = -DPLUGIN $(GTK2_CFLAGS) -image_libs = $(GTK2_LIBS) -image_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/launchbar/.gitignore b/plugins/launchbar/.gitignore deleted file mode 100644 index c07f3ac..0000000 --- a/plugins/launchbar/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -launchbar.o -launchbar.d -liblaunchbar.so diff --git a/plugins/launchbar/Makefile b/plugins/launchbar/Makefile deleted file mode 100644 index 27e0c63..0000000 --- a/plugins/launchbar/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -launchbar_src = launchbar.c -launchbar_cflags = -DPLUGIN $(GTK2_CFLAGS) -launchbar_libs = $(GTK2_LIBS) -launchbar_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/launchbar/launchbar.c b/plugins/launchbar/launchbar.c index c9c0dc4..ae04e4e 100644 --- a/plugins/launchbar/launchbar.c +++ b/plugins/launchbar/launchbar.c @@ -53,7 +53,7 @@ typedef struct btn { gchar *action; } btn; -#define MAXBUTTONS 20 +#define MAXBUTTONS 40 typedef struct launchbar_priv { plugin_instance plugin; GtkWidget *box; diff --git a/plugins/mem/.gitignore b/plugins/mem/.gitignore deleted file mode 100644 index 4adf20f..0000000 --- a/plugins/mem/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -mem.o -mem.d -libmem.so diff --git a/plugins/mem/Makefile b/plugins/mem/Makefile deleted file mode 100644 index 17965a8..0000000 --- a/plugins/mem/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -mem_src = mem.c -mem_cflags = -DPLUGIN $(GTK2_CFLAGS) -mem_libs = $(GTK2_LIBS) -mem_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/mem2/.gitignore b/plugins/mem2/.gitignore deleted file mode 100644 index e08398d..0000000 --- a/plugins/mem2/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -mem2.o -mem2.d -libmem2.so diff --git a/plugins/mem2/Makefile b/plugins/mem2/Makefile deleted file mode 100644 index c828dd0..0000000 --- a/plugins/mem2/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -mem2_src = mem2.c -mem2_cflags = -DPLUGIN $(GTK2_CFLAGS) -mem2_libs = $(GTK2_LIBS) -mem2_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/menu/.gitignore b/plugins/menu/.gitignore deleted file mode 100644 index b8b598a..0000000 --- a/plugins/menu/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -menu.o -menu.d -system_menu.o -system_menu.d -libmenu.so diff --git a/plugins/menu/Makefile b/plugins/menu/Makefile deleted file mode 100644 index 29f7f83..0000000 --- a/plugins/menu/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -menu_src = menu.c \ - system_menu.c -menu_cflags = -DPLUGIN $(GTK2_CFLAGS) -menu_libs = $(GTK2_LIBS) -menu_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/meter/.gitignore b/plugins/meter/.gitignore deleted file mode 100644 index 7f853ba..0000000 --- a/plugins/meter/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -meter.o -meter.d -libmeter.so diff --git a/plugins/meter/Makefile b/plugins/meter/Makefile deleted file mode 100644 index 6875585..0000000 --- a/plugins/meter/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -meter_src = meter.c -meter_cflags = -DPLUGIN $(GTK2_CFLAGS) -meter_libs = $(GTK2_LIBS) -meter_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/net/.gitignore b/plugins/net/.gitignore deleted file mode 100644 index 3161da5..0000000 --- a/plugins/net/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -net.o -net.d -libnet.so diff --git a/plugins/net/Makefile b/plugins/net/Makefile deleted file mode 100644 index d400a84..0000000 --- a/plugins/net/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -net_src = net.c -net_cflags = -DPLUGIN $(GTK2_CFLAGS) -net_libs = $(GTK2_LIBS) -net_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/net/net.c b/plugins/net/net.c index 2a60f44..0b9dcf9 100644 --- a/plugins/net/net.c +++ b/plugins/net/net.c @@ -60,17 +60,20 @@ net_get_load_real(net_priv *c, struct net_stat *net) stat = fopen("/proc/net/dev", "r"); if(!stat) return -1; - if (fgets(buf, 256, stat)); - if (fgets(buf, 256, stat)); + + (void)fgets(buf, 256, stat); + (void)fgets(buf, 256, stat); while (!s && !feof(stat) && fgets(buf, 256, stat)) s = g_strrstr(buf, c->iface); fclose(stat); if (!s) return -1; + s = g_strrstr(s, ":"); if (!s) return -1; + s++; if (sscanf(s, "%lu %*d %*d %*d %*d %*d %*d %*d %lu", diff --git a/plugins/pager/.gitignore b/plugins/pager/.gitignore deleted file mode 100644 index 10debd8..0000000 --- a/plugins/pager/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -pager.o -pager.d -libpager.so diff --git a/plugins/pager/Makefile b/plugins/pager/Makefile deleted file mode 100644 index 0970f35..0000000 --- a/plugins/pager/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -pager_src = pager.c -pager_cflags = -DPLUGIN $(GTK2_CFLAGS) -pager_libs = $(GTK2_LIBS) -pager_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/pager/pager.c b/plugins/pager/pager.c index ebe2052..aeabdef 100644 --- a/plugins/pager/pager.c +++ b/plugins/pager/pager.c @@ -27,10 +27,13 @@ #include +#include +#include #include "panel.h" #include "misc.h" #include "plugin.h" +#include "data/images/default.xpm" #include "gtkbgbox.h" //#define DEBUGPRN @@ -49,6 +52,8 @@ typedef struct _task { char *name, *iname; net_wm_state nws; net_wm_window_type nwwt; + GdkPixbuf *pixbuf; + unsigned int using_netwm_icon:1; } task; typedef struct _desk desk; @@ -81,6 +86,7 @@ struct _pager_priv { task *focusedtask; FbBg *fbbg; gint dah, daw; + GdkPixbuf *gen_pixbuf; }; @@ -152,6 +158,9 @@ task_remove_stale(Window *win, task *t, pager_priv *p) static gboolean task_remove_all(Window *win, task *t, pager_priv *p) { + if (t->pixbuf != NULL) + g_object_unref(t->pixbuf); + g_free(t); return TRUE; } @@ -221,7 +230,47 @@ task_update_pix(task *t, desk *d) widget->style->fg_gc[GTK_STATE_SELECTED] : widget->style->fg_gc[GTK_STATE_NORMAL], FALSE, - x, y, w, h); + x, y, w-1, h); + + if (w>=10 && h>=10) { + GdkPixbuf* source_buf = t->pixbuf; + if (source_buf == NULL) + source_buf = d->pg->gen_pixbuf; + + /* determine how much to scale */ + GdkPixbuf* scaled = source_buf; + int scale = 16; + int noscale = 1; + int smallest = ( (wpix, + NULL, + scaled, + 0, 0, + pixx, pixy, + -1, -1, + GDK_RGB_DITHER_NONE, + 0, 0); + + /* free it if its been scaled and its not the default */ + if (!noscale && t->pixbuf != NULL) + g_object_unref(scaled); + } RET(); } @@ -491,6 +540,315 @@ desk_free(pager_priv *pg, int i) } +/***************************************************************** + * Stuff to grab icons from windows - ripped from taskbar.c * + *****************************************************************/ + +static GdkColormap* +get_cmap (GdkPixmap *pixmap) +{ + GdkColormap *cmap; + + ENTER; + cmap = gdk_drawable_get_colormap (pixmap); + if (cmap) + g_object_ref (G_OBJECT (cmap)); + + if (cmap == NULL) + { + if (gdk_drawable_get_depth (pixmap) == 1) + { + /* try null cmap */ + cmap = NULL; + } + else + { + /* Try system cmap */ + GdkScreen *screen = gdk_drawable_get_screen (GDK_DRAWABLE (pixmap)); + cmap = gdk_screen_get_system_colormap (screen); + g_object_ref (G_OBJECT (cmap)); + } + } + + /* Be sure we aren't going to blow up due to visual mismatch */ + if (cmap && + (gdk_colormap_get_visual (cmap)->depth != + gdk_drawable_get_depth (pixmap))) + cmap = NULL; + + RET(cmap); +} + +static GdkPixbuf* +_wnck_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest, + Pixmap xpixmap, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height) +{ + GdkDrawable *drawable; + GdkPixbuf *retval; + GdkColormap *cmap; + + ENTER; + retval = NULL; + + drawable = gdk_xid_table_lookup (xpixmap); + + if (drawable) + g_object_ref (G_OBJECT (drawable)); + else + drawable = gdk_pixmap_foreign_new (xpixmap); + + cmap = get_cmap (drawable); + + /* GDK is supposed to do this but doesn't in GTK 2.0.2, + * fixed in 2.0.3 + */ + if (width < 0) + gdk_drawable_get_size (drawable, &width, NULL); + if (height < 0) + gdk_drawable_get_size (drawable, NULL, &height); + + retval = gdk_pixbuf_get_from_drawable (dest, + drawable, + cmap, + src_x, src_y, + dest_x, dest_y, + width, height); + + if (cmap) + g_object_unref (G_OBJECT (cmap)); + g_object_unref (G_OBJECT (drawable)); + + RET(retval); +} + +static GdkPixbuf* +apply_mask (GdkPixbuf *pixbuf, + GdkPixbuf *mask) +{ + int w, h; + int i, j; + GdkPixbuf *with_alpha; + guchar *src; + guchar *dest; + int src_stride; + int dest_stride; + + ENTER; + w = MIN (gdk_pixbuf_get_width (mask), gdk_pixbuf_get_width (pixbuf)); + h = MIN (gdk_pixbuf_get_height (mask), gdk_pixbuf_get_height (pixbuf)); + + with_alpha = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); + + dest = gdk_pixbuf_get_pixels (with_alpha); + src = gdk_pixbuf_get_pixels (mask); + + dest_stride = gdk_pixbuf_get_rowstride (with_alpha); + src_stride = gdk_pixbuf_get_rowstride (mask); + + i = 0; + while (i < h) + { + j = 0; + while (j < w) + { + guchar *s = src + i * src_stride + j * 3; + guchar *d = dest + i * dest_stride + j * 4; + + /* s[0] == s[1] == s[2], they are 255 if the bit was set, 0 + * otherwise + */ + if (s[0] == 0) + d[3] = 0; /* transparent */ + else + d[3] = 255; /* opaque */ + + ++j; + } + + ++i; + } + + RET(with_alpha); +} + +static void +free_pixels (guchar *pixels, gpointer data) +{ + ENTER; + g_free (pixels); + RET(); +} + +static guchar * +argbdata_to_pixdata (gulong *argb_data, int len) +{ + guchar *p, *ret; + int i; + + ENTER; + ret = p = g_new (guchar, len * 4); + if (!ret) + RET(NULL); + /* One could speed this up a lot. */ + i = 0; + while (i < len) { + guint32 argb; + guint32 rgba; + + argb = argb_data[i]; + rgba = (argb << 8) | (argb >> 24); + + *p = rgba >> 24; + ++p; + *p = (rgba >> 16) & 0xff; + ++p; + *p = (rgba >> 8) & 0xff; + ++p; + *p = rgba & 0xff; + ++p; + + ++i; + } + RET(ret); +} + +static GdkPixbuf * +get_netwm_icon(Window tkwin, int iw, int ih) +{ + gulong *data; + GdkPixbuf *ret = NULL; + int n; + guchar *p; + GdkPixbuf *src; + int w, h; + + ENTER; + data = get_xaproperty(tkwin, a_NET_WM_ICON, XA_CARDINAL, &n); + if (!data) + RET(NULL); + + /* loop through all icons in data to find best fit */ + if (0) { + gulong *tmp; + int len; + + len = n/sizeof(gulong); + tmp = data; + while (len > 2) { + int size = tmp[0] * tmp[1]; + DBG("sub-icon: %dx%d %d bytes\n", tmp[0], tmp[1], size * 4); + len -= size + 2; + tmp += size; + } + } + + if (0) { + int i, j, nn; + + nn = MIN(10, n); + p = (guchar *) data; + for (i = 0; i < nn; i++) { + for (j = 0; j < sizeof(gulong); j++) + ERR("%02x ", (guint) p[i*sizeof(gulong) + j]); + ERR("\n"); + } + } + + /* check that data indeed represents icon in w + h + ARGB[] format + * with 16x16 dimension at least */ + if (n < (16 * 16 + 1 + 1)) { + ERR("win %lx: icon is too small or broken (size=%d)\n", tkwin, n); + goto out; + } + w = data[0]; + h = data[1]; + /* check that sizes are in 64-256 range */ + if (w < 16 || w > 256 || h < 16 || h > 256) { + ERR("win %lx: icon size (%d, %d) is not in 64-256 range\n", + tkwin, w, h); + goto out; + } + + DBG("orig %dx%d dest %dx%d\n", w, h, iw, ih); + p = argbdata_to_pixdata(data + 2, w * h); + if (!p) + goto out; + src = gdk_pixbuf_new_from_data (p, GDK_COLORSPACE_RGB, TRUE, + 8, w, h, w * 4, free_pixels, NULL); + if (src == NULL) + goto out; + ret = src; + if (w != iw || h != ih) { + ret = gdk_pixbuf_scale_simple(src, iw, ih, GDK_INTERP_HYPER); + g_object_unref(src); + } + +out: + XFree(data); + RET(ret); +} + +static GdkPixbuf* +get_wm_icon(Window tkwin, int iw, int ih) +{ + XWMHints *hints; + Pixmap xpixmap = None, xmask = None; + Window win; + unsigned int w, h; + int sd; + GdkPixbuf *ret, *masked, *pixmap, *mask = NULL; + + ENTER; + hints = XGetWMHints(GDK_DISPLAY(), tkwin); + DBG("\nwm_hints %s\n", hints ? "ok" : "failed"); + if (!hints) + RET(NULL); + + if ((hints->flags & IconPixmapHint)) + xpixmap = hints->icon_pixmap; + if ((hints->flags & IconMaskHint)) + xmask = hints->icon_mask; + DBG("flag=%ld xpixmap=%lx flag=%ld xmask=%lx\n", (hints->flags & IconPixmapHint), xpixmap, + (hints->flags & IconMaskHint), xmask); + XFree(hints); + if (xpixmap == None) + RET(NULL); + + if (!XGetGeometry (GDK_DISPLAY(), xpixmap, &win, &sd, &sd, &w, &h, + (guint *)&sd, (guint *)&sd)) { + DBG("XGetGeometry failed for %x pixmap\n", (unsigned int)xpixmap); + RET(NULL); + } + DBG("tkwin=%x icon pixmap w=%d h=%d\n", tkwin, w, h); + pixmap = _wnck_gdk_pixbuf_get_from_pixmap (NULL, xpixmap, 0, 0, 0, 0, w, h); + if (!pixmap) + RET(NULL); + if (xmask != None && XGetGeometry (GDK_DISPLAY(), xmask, + &win, &sd, &sd, &w, &h, (guint *)&sd, (guint *)&sd)) { + mask = _wnck_gdk_pixbuf_get_from_pixmap (NULL, xmask, 0, 0, 0, 0, w, h); + + if (mask) { + masked = apply_mask (pixmap, mask); + g_object_unref (G_OBJECT (pixmap)); + g_object_unref (G_OBJECT (mask)); + pixmap = masked; + } + } + if (!pixmap) + RET(NULL); + ret = gdk_pixbuf_scale_simple (pixmap, iw, ih, GDK_INTERP_TILES); + g_object_unref(pixmap); + + RET(ret); +} + + /***************************************************************** * Netwm/WM Interclient Communication * *****************************************************************/ @@ -572,6 +930,11 @@ do_net_client_list_stacking(FbEv *ev, pager_priv *p) get_net_wm_state(t->win, &t->nws); get_net_wm_window_type(t->win, &t->nwwt); task_get_sizepos(t); + t->pixbuf = get_netwm_icon(t->win, 16, 16); + t->using_netwm_icon = (t->pixbuf != NULL); + if (!t->using_netwm_icon) { + t->pixbuf = get_wm_icon(t->win, 16, 16); + } g_hash_table_insert(p->htable, &t->win, t); DBG("add %lx\n", t->win); desk_set_dirty_by_win(p, t); @@ -787,6 +1150,9 @@ pager_constructor(plugin_instance *plug) g_signal_connect(G_OBJECT(pg->fbbg), "changed", G_CALLBACK(pager_bg_changed), pg); } + + pg->gen_pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)icon_xpm); + pager_rebuild_all(fbev, pg); gdk_window_add_filter(NULL, (GdkFilterFunc)pager_event_filter, pg ); diff --git a/plugins/separator/.gitignore b/plugins/separator/.gitignore deleted file mode 100644 index a8ff622..0000000 --- a/plugins/separator/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -separator.o -separator.d -libseparator.so diff --git a/plugins/separator/Makefile b/plugins/separator/Makefile deleted file mode 100644 index b748834..0000000 --- a/plugins/separator/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -separator_src = separator.c -separator_cflags = -DPLUGIN $(GTK2_CFLAGS) -separator_libs = $(GTK2_LIBS) -separator_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/space/.gitignore b/plugins/space/.gitignore deleted file mode 100644 index 9df367b..0000000 --- a/plugins/space/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -space.o -space.d -libspace.so diff --git a/plugins/space/Makefile b/plugins/space/Makefile deleted file mode 100644 index d735c28..0000000 --- a/plugins/space/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -space_src = space.c -space_cflags = -DPLUGIN $(GTK2_CFLAGS) -space_libs = $(GTK2_LIBS) -space_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/systray/.gitignore b/plugins/systray/.gitignore deleted file mode 100644 index 3233d74..0000000 --- a/plugins/systray/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -egg-marshal.o -egg-marshal.d -eggtraymanager.o -eggtraymanager.d -fixedtip.o -fixedtip.d -main.o -main.d -libtray.so diff --git a/plugins/systray/Makefile b/plugins/systray/Makefile deleted file mode 100644 index be212ca..0000000 --- a/plugins/systray/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -tray_src = egg-marshal.c \ - eggtraymanager.c \ - fixedtip.c \ - main.c -tray_cflags = -DPLUGIN $(GTK2_CFLAGS) -tray_libs = $(GTK2_LIBS) -tray_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/systray/egg-marshal.c b/plugins/systray/egg-marshal.c deleted file mode 100644 index 2fb5bb4..0000000 --- a/plugins/systray/egg-marshal.c +++ /dev/null @@ -1,2 +0,0 @@ -#include "eggmarshalers.h" -#include "eggmarshalers.c" diff --git a/plugins/systray/libsystray.so b/plugins/systray/libsystray.so deleted file mode 100755 index ad28e1f..0000000 Binary files a/plugins/systray/libsystray.so and /dev/null differ diff --git a/plugins/taskbar/.gitignore b/plugins/taskbar/.gitignore deleted file mode 100644 index ad7eefa..0000000 --- a/plugins/taskbar/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -taskbar.o -taskbar.d -libtaskbar.so diff --git a/plugins/taskbar/Makefile b/plugins/taskbar/Makefile deleted file mode 100644 index 705012e..0000000 --- a/plugins/taskbar/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -taskbar_src = taskbar.c -taskbar_cflags = -DPLUGIN $(GTK2_CFLAGS) -taskbar_libs = $(GTK2_LIBS) -taskbar_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/tclock/.gitignore b/plugins/tclock/.gitignore deleted file mode 100644 index e7c28f6..0000000 --- a/plugins/tclock/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -tclock.o -tclock.d -libtclock.so diff --git a/plugins/tclock/Makefile b/plugins/tclock/Makefile deleted file mode 100644 index 47d1a82..0000000 --- a/plugins/tclock/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -tclock_src = tclock.c -tclock_cflags = -DPLUGIN $(GTK2_CFLAGS) -tclock_libs = $(GTK2_LIBS) -tclock_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/tray/egg-marshal.c b/plugins/tray/egg-marshal.c new file mode 100644 index 0000000..a2ef1e3 --- /dev/null +++ b/plugins/tray/egg-marshal.c @@ -0,0 +1,2 @@ +#include "eggmarshalers.h" +#include "eggmarshalers.c.inc" diff --git a/plugins/systray/eggmarshalers.c b/plugins/tray/eggmarshalers.c.inc similarity index 100% rename from plugins/systray/eggmarshalers.c rename to plugins/tray/eggmarshalers.c.inc diff --git a/plugins/systray/eggmarshalers.h b/plugins/tray/eggmarshalers.h similarity index 100% rename from plugins/systray/eggmarshalers.h rename to plugins/tray/eggmarshalers.h diff --git a/plugins/systray/eggtraymanager.c b/plugins/tray/eggtraymanager.c similarity index 100% rename from plugins/systray/eggtraymanager.c rename to plugins/tray/eggtraymanager.c diff --git a/plugins/systray/eggtraymanager.h b/plugins/tray/eggtraymanager.h similarity index 100% rename from plugins/systray/eggtraymanager.h rename to plugins/tray/eggtraymanager.h diff --git a/plugins/systray/fixedtip.c b/plugins/tray/fixedtip.c similarity index 100% rename from plugins/systray/fixedtip.c rename to plugins/tray/fixedtip.c diff --git a/plugins/systray/fixedtip.h b/plugins/tray/fixedtip.h similarity index 100% rename from plugins/systray/fixedtip.h rename to plugins/tray/fixedtip.h diff --git a/plugins/systray/main.c b/plugins/tray/main.c similarity index 100% rename from plugins/systray/main.c rename to plugins/tray/main.c diff --git a/plugins/unstable/Makefile b/plugins/unstable/Makefile deleted file mode 100644 index 53a6e32..0000000 --- a/plugins/unstable/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -SUBDIRS := test - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/unstable/test/Makefile b/plugins/unstable/test/Makefile deleted file mode 100644 index 890c533..0000000 --- a/plugins/unstable/test/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../../.. - -test_src = test.c -test_cflags = $(GTK2_CFLAGS) -test_libs = $(GTK2_LIBS) -test_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/user/.gitignore b/plugins/user/.gitignore deleted file mode 100644 index f220c49..0000000 --- a/plugins/user/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -user.o -user.d -libuser.so diff --git a/plugins/user/Makefile b/plugins/user/Makefile deleted file mode 100644 index 8025a41..0000000 --- a/plugins/user/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -user_src = user.c -user_cflags = -DPLUGIN $(GTK2_CFLAGS) -user_libs = $(GTK2_LIBS) -user_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/volume/.gitignore b/plugins/volume/.gitignore deleted file mode 100644 index 1e9969e..0000000 --- a/plugins/volume/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -volume.o -volume.d -libvolume.so diff --git a/plugins/volume/Makefile b/plugins/volume/Makefile deleted file mode 100644 index 235a9fc..0000000 --- a/plugins/volume/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -volume_src = volume.c -volume_cflags = -DPLUGIN $(GTK2_CFLAGS) -volume_libs = $(GTK2_LIBS) -volume_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/plugins/wincmd/.gitignore b/plugins/wincmd/.gitignore deleted file mode 100644 index 09b285e..0000000 --- a/plugins/wincmd/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -wincmd.o -wincmd.d -libwincmd.so diff --git a/plugins/wincmd/Makefile b/plugins/wincmd/Makefile deleted file mode 100644 index da8fc60..0000000 --- a/plugins/wincmd/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := ../.. - -wincmd_src = wincmd.c -wincmd_cflags = -DPLUGIN $(GTK2_CFLAGS) -wincmd_libs = $(GTK2_LIBS) -wincmd_type = lib - -include $(TOPDIR)/.config/rules.mk diff --git a/po/.gitignore b/po/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/po/Makefile b/po/Makefile deleted file mode 100644 index 4284b57..0000000 --- a/po/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := .. - -include $(TOPDIR)/.config/rules.mk diff --git a/po/it_IT.UTF-8.mo b/po/it_IT.UTF-8.mo new file mode 100644 index 0000000..faa45fa Binary files /dev/null and b/po/it_IT.UTF-8.mo differ diff --git a/po/it_IT.UTF-8.po b/po/it_IT.UTF-8.po new file mode 100644 index 0000000..bd461cc --- /dev/null +++ b/po/it_IT.UTF-8.po @@ -0,0 +1,216 @@ +# French translations for fbpanel package. +# Copyright (C) 2010 THE fbpanel'S COPYRIGHT HOLDER +# This file is distributed under the same license as the fbpanel package. +# Automatically generated, 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: fbpanel 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-25 02:07+0200\n" +"PO-Revision-Date: 2016-01-25 02:07+0200\n" +"Last-Translator: Automaticaly generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: panel/gconf_panel.c:57 +msgid "Visual Effects" +msgstr "Effetti grafici" + +#: panel/gconf_panel.c:65 +msgid "Transparency" +msgstr "Trasparenza" + +#: panel/gconf_panel.c:69 +msgid "Color settings" +msgstr "Colori" + +#: panel/gconf_panel.c:79 +msgid "Round corners" +msgstr "Angoli arrotondati" + +#: panel/gconf_panel.c:83 +msgid "Radius is " +msgstr "Raggio di " + +#: panel/gconf_panel.c:87 panel/gconf_panel.c:101 panel/misc.c:89 +msgid "pixels" +msgstr "pixel" + +#: panel/gconf_panel.c:93 +msgid "Autohide" +msgstr "Nascondi automaticamente" + +#: panel/gconf_panel.c:97 +msgid "Height when hidden is " +msgstr "Altezza quando nascosto " + +#: panel/gconf_panel.c:106 +msgid "Max Element Height" +msgstr "Altezza massima elemento" + +#: panel/gconf_panel.c:138 +msgid "Properties" +msgstr "Proprietà" + +#: panel/gconf_panel.c:146 +msgid "Do not cover by maximized windows" +msgstr "Non coperto dalle finestre massimizzate" + +#: panel/gconf_panel.c:150 +msgid "Set 'Dock' type" +msgstr "Tipo 'Dock'" + +#: panel/gconf_panel.c:155 +msgid "Set stacking layer" +msgstr "Layer" + +#: panel/gconf_panel.c:159 +msgid "Panel is " +msgstr "Il pannello è " + +#: panel/gconf_panel.c:164 +msgid "all windows" +msgstr "tutte le finestre" + +#: panel/gconf_panel.c:209 +msgid "Geometry" +msgstr "Geometria" + +#: panel/gconf_panel.c:216 +msgid "Width" +msgstr "Larghezza" + +#: panel/gconf_panel.c:226 +msgid "Height" +msgstr "Altezza" + +#: panel/gconf_panel.c:231 +msgid "Edge" +msgstr "Bordo" + +#: panel/gconf_panel.c:236 +msgid "Allignment" +msgstr "Allineamento" + +#: panel/gconf_panel.c:241 +msgid "Margin" +msgstr "Margine" + +#: panel/gconf_panel.c:285 +#, c-format +msgid "" +"You're using '%s' profile, stored at\n" +"%s" +msgstr "" +"Stai usando il profilo '%s', salvato in\n" +"%s" + +#: panel/gconf_panel.c:388 +msgid "Panel" +msgstr "Pannello" + +#: panel/gconf_panel.c:393 +msgid "Plugins" +msgstr "Plugin" + +#: panel/gconf_panel.c:398 +msgid "Profile" +msgstr "Profilo" +#: panel/misc.c:75 panel/misc.c:81 +msgid "left" +msgstr "sinistra" + +#: panel/misc.c:76 panel/misc.c:82 +msgid "right" +msgstr "destra" + +#: panel/misc.c:77 +msgid "center" +msgstr "centro" + +#: panel/misc.c:83 +msgid "top" +msgstr "alto" + +#: panel/misc.c:84 +msgid "bottom" +msgstr "basso" + +#: panel/misc.c:88 +msgid "dynamic" +msgstr "dinamico" + +#: panel/misc.c:90 +#, c-format +msgid "% of screen" +msgstr "% dello schermo" + +#: panel/misc.c:94 +msgid "pixel" +msgstr "pixel" + +#: panel/misc.c:109 +msgid "above" +msgstr "sopra" + +#: panel/misc.c:110 +msgid "below" +msgstr "sotto" + +#: panel/panel.c:464 +msgid "translator-credits" +msgstr "Man from Mars " + +#: plugins/menu/system_menu.c:24 +msgid "Audio & Video" +msgstr "Audio e Video" + +#: plugins/menu/system_menu.c:25 +msgid "Education" +msgstr "Istruzione" + +#: plugins/menu/system_menu.c:26 +msgid "Game" +msgstr "Giochi" + +#: plugins/menu/system_menu.c:27 +msgid "Graphics" +msgstr "Grafica" + +#: plugins/menu/system_menu.c:28 +msgid "Network" +msgstr "Rete" + +#: plugins/menu/system_menu.c:29 +msgid "Office" +msgstr "Ufficio" + +#: plugins/menu/system_menu.c:30 +msgid "Settings" +msgstr "Impostazioni" + +#: plugins/menu/system_menu.c:31 +msgid "System" +msgstr "Sistema" + +#: plugins/menu/system_menu.c:32 +msgid "Utilities" +msgstr "Strumenti" + +#: plugins/menu/system_menu.c:33 +msgid "Development" +msgstr "Sviluppo" + +#: plugins/taskbar/taskbar.c:1267 +msgid "Raise" +msgstr "Ripristina" + +#: plugins/taskbar/taskbar.c:1274 +msgid "Iconify" +msgstr "Riduci a icona" + diff --git a/scripts/.gitignore b/scripts/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/Makefile b/scripts/Makefile deleted file mode 100644 index 4284b57..0000000 --- a/scripts/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -## miniconf makefiles ## 1.1 ## - -TOPDIR := .. - -include $(TOPDIR)/.config/rules.mk diff --git a/scripts/create_po.sh b/scripts/create_po.sh deleted file mode 100755 index 55db0b0..0000000 --- a/scripts/create_po.sh +++ /dev/null @@ -1,63 +0,0 @@ -#/bin/bash - -function info() -{ - cat < $list - -# Create POT file and set charset to be UTF-8 -2>/dev/null xgettext --package-name=$package --package-version=$version \ - --default-domain=$package --from-code=UTF-8 \ - --force-po -k_ -kc_ -f $list -o - |\ -sed '/^"Content-Type:/ s/CHARSET/UTF-8/' > $pot - -# create language translation files, POs -if [ -n "$update" ]; then - old=/tmp/old-$$ - cp $po $old -fi -tr="${translator:-Automaticaly generated}" -2>/dev/null msginit --no-translator --locale=$locale --input=$pot -o - |\ -sed "/\"Last-Translator:/ s/Auto.*\\\n/$tr\\\n/" > $po -if [ -n "$update" ]; then - scripts/update_po.sh --old=$old --new=$po - rm $old -fi -echo Created $po -rm $pot \ No newline at end of file diff --git a/scripts/custom.sh b/scripts/custom.sh deleted file mode 100644 index e6995eb..0000000 --- a/scripts/custom.sh +++ /dev/null @@ -1,30 +0,0 @@ - - -######################### -## Custom Settings ## -######################### - -# Note 1: PWD will be that of configure, not scripts directory, so to run script from -# this directory refer it as 'scripts/name' - -# Note 2: values will be evaluated in the same order they were added, so -# if you want libdir's default value to be '$eprefix/lib', add it after prefix - -add_var package "package name, e.g fbpanel or mplayer" fbpanel -add_var version "package version, e.g 6.2 or 1.4.5-alpha2" 6.2 - -# Custom -add_feature dependency "disable dependency tracking" disabled - -add_var glib_cflags "glib cflags" '`RFS=$rfs scripts/rfs-pkg-config --cflags glib-2.0`' -add_var gtk_cflags "gtk cflags" '`RFS=$rfs scripts/rfs-pkg-config --cflags gtk+-2.0`' - -add_var glib_libs "glib libs" '`RFS=$rfs scripts/rfs-pkg-config --libs glib-2.0`' -add_var gtk_libs "gtk libs" '`RFS=$rfs scripts/rfs-pkg-config --libs gtk+-2.0`' - -add_var cflagsx "C flags" '-I$topdir/panel $glib_cflags $gtk_cflags -fPIC' -add_var ldflagsx "linker flags" '$glib_libs $gtk_libs' - -add_var gmodule_libs "gmodule libs" '`scripts/rfs-pkg-config --libs gmodule-2.0`' - -add_feature static_build "build all pluginis into main binary" disabled diff --git a/scripts/endianess.sh b/scripts/endianess.sh deleted file mode 100755 index 83bd5ac..0000000 --- a/scripts/endianess.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# When cross compiling, you may put cross compiler directory -# in PATH before native gcc (aka spoofing), or you may set CC -# to exact name of cross compiler: -# CC=/opt/ppc_gcc/bin/gcc endianess - -# x86 and friends are considerd LITTLE endian, all others are BIG -a=`${CC:-gcc} -v 2>&1 | grep Target` -[ $? -ne 0 ] && exit 1 -#echo $a - -if [ "${a/86/}" != "$a" ]; then - echo LITTLE -else - echo BIG -fi - diff --git a/scripts/funcs.sh b/scripts/funcs.sh deleted file mode 100644 index 723e7a5..0000000 --- a/scripts/funcs.sh +++ /dev/null @@ -1,40 +0,0 @@ - -function error () -{ - echo "$@" - exit 1 -} - -function print_var () -{ - eval echo \"$1=\$$1\" -} - -function check_var () -{ - eval [ -n \"\$$1\" ] && return - [ -z "$2" ] && error "Var $1 was not set" - eval $1="$2" -} - -function parse_argv () -{ - while [ $# -gt 0 ]; do - if [ "$1" == "--help" ]; then - info - help - exit 0 - fi - if [ "${1:0:2}" != "--" ]; then - error "$1 - not a parameter" - fi - tmp="${1:2}" - var=${tmp%%=*} - val=${tmp#*=} - if [ "$var" == "$val" ]; then - let $var=x - fi - eval "$var=\"$val\"" - shift - done -} \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh deleted file mode 100755 index f842b92..0000000 --- a/scripts/install.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -usage () -{ - echo "install.sh " -} - - -[ $# -eq 3 ] && exit 0 -[ $# -lt 4 ] && usage && exit 1 - -idir=${DESTDIR}$2 -p1=$1 -p2=$3 -shift 3 - -echo install -m $p1 -d "$idir" -install -m $p1 -d "$idir" -echo install -m $p2 "$@" "$idir" -install -m $p2 "$@" "$idir" - diff --git a/scripts/install_locale.sh b/scripts/install_locale.sh deleted file mode 100755 index 92b88fb..0000000 --- a/scripts/install_locale.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -dir=/tmp/lo-$$ -mkdir $dir -cp $1.mo $dir -cd $dir -mv $1.mo fbpanel.mo - -# Create name for destination dir. -# Locale has format LL_CC.ENC. (LL - language, CC - country, ENC - encoding) -# Name is LL_CC. but if CC is equal to LL, then name is only LL. -IFS="_" a=(${1%%.*}) -lang=${a[0]} -country=${a[1]} -if [ "${lang^^}" == "$country" ]; then - LC="${lang}" -else - LC="${lang}_${country}" -fi - -install=/home/aanatoly/src/fbpanel/trunk/scripts/install.sh -${install} 755 /home/aanatoly/.local/share/locale/$LC/LC_MESSAGES 644 fbpanel.mo -rm -rf $dir - diff --git a/scripts/install_locale.sh.in b/scripts/install_locale.sh.in deleted file mode 100755 index 15c2154..0000000 --- a/scripts/install_locale.sh.in +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -dir=/tmp/lo-$$ -mkdir $dir -cp $1.mo $dir -cd $dir -mv $1.mo %%package%%.mo - -# Create name for destination dir. -# Locale has format LL_CC.ENC. (LL - language, CC - country, ENC - encoding) -# Name is LL_CC. but if CC is equal to LL, then name is only LL. -IFS="_" a=(${1%%.*}) -lang=${a[0]} -country=${a[1]} -if [ "${lang^^}" == "$country" ]; then - LC="${lang}" -else - LC="${lang}_${country}" -fi - -install=%%topdir%%/scripts/install.sh -${install} 755 %%localedir%%/$LC/LC_MESSAGES 644 %%package%%.mo -rm -rf $dir - diff --git a/scripts/mk_tar b/scripts/mk_tar deleted file mode 100755 index 3d2f9ac..0000000 --- a/scripts/mk_tar +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - - -function info() -{ - cat <" - echo " tar - tar file with latest proj version" - echo "Must be run from top directory" - exit $1 -} - -[ $# -ne 1 ] && usage 1 - -tar="$1" -tar --strip-components=1 --exclude doc --exclude src \ - --keep-newer-files -xvf "$tar" - diff --git a/scripts/update_po.sh b/scripts/update_po.sh deleted file mode 100755 index a077b8e..0000000 --- a/scripts/update_po.sh +++ /dev/null @@ -1,59 +0,0 @@ -#/bin/bash - -function info() -{ - cat < $tmp -mv $tmp $new - -# code diff --git a/version b/version deleted file mode 100644 index 4fedf1d..0000000 --- a/version +++ /dev/null @@ -1 +0,0 @@ -7.0 diff --git a/version.in b/version.in new file mode 100644 index 0000000..cab46ae --- /dev/null +++ b/version.in @@ -0,0 +1 @@ +@CMAKE_PROJECT_VERSION@ diff --git a/www/Makefile b/www/Makefile deleted file mode 100644 index 647316a..0000000 --- a/www/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = shots plugins -TOPDIR = . -include $(TOPDIR)/Makefile.common - - -all: index.html docs.html diff --git a/www/plugins/Makefile b/www/plugins/Makefile deleted file mode 100644 index 8aee12c..0000000 --- a/www/plugins/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -TOPDIR = .. -include $(TOPDIR)/Makefile.common - -SRC = ../plugins - -all: $(SRC).html - -$(SRC).thtml: $(wildcard */* */) ./mk_gallery -#./mk_gallery $@ - @echo "coming soon..." > $@ - -clean: clean2 - -clean2: - $(RM) $(SRC).thtml diff --git a/www/shots/Makefile b/www/shots/Makefile deleted file mode 100644 index 30e5cbf..0000000 --- a/www/shots/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -TOPDIR = .. -include $(TOPDIR)/Makefile.common - -SRC = ../shots - -all: $(SRC).html - -$(SRC).thtml: $(wildcard */* */) ./mk_gallery - ./mk_gallery $@ - -clean: clean2 - -clean2: - $(RM) $(SRC).thtml \ No newline at end of file