paraslash.git
9 years agoparaslash 0.5.3 v0.5.3
Andre Noll [Fri, 1 Aug 2014 12:23:58 +0000 (14:23 +0200)]
paraslash 0.5.3

9 years agobuild: Do not hardcode gcc in depend.sh.
Andre Noll [Thu, 24 Jul 2014 20:42:28 +0000 (22:42 +0200)]
build: Do not hardcode gcc in depend.sh.

Although the clang compiler understands the -MM and -MG options,
we currently rely on gcc to generate the dependency files. Of course
this fails on systems where only clang is installed. The right fix
would be to use the make variable $(CC), but let's go for the minimal
fix that replaces gcc by cc in depend.sh for now.

9 years agobuild: Properly unset CPPFLAGS, LDFLAGS, LIBS.
Andre Noll [Sun, 20 Apr 2014 20:50:45 +0000 (20:50 +0000)]
build: Properly unset CPPFLAGS, LDFLAGS, LIBS.

Currently the directories specified via --with-ogg-headers and
--with-ogg-libs are taken into account also for vorbis/speex/opus
detection. This patch makes sure we start with a pristine values
for the three variables.

9 years agobuild: Compilie opus*.c files with ogg_cppflags.
Andre Noll [Thu, 24 Jul 2014 21:01:09 +0000 (23:01 +0200)]
build: Compilie opus*.c files with ogg_cppflags.

These files include ogg/ogg.h, so we must pass $(ogg_cppflags)
to avoid build failure in case ogg headers are installed at a
non-standard location.

9 years agobuild: Fix --with-gcrypt-headers and --with-vorbis-headers.
Andre Noll [Fri, 2 May 2014 20:07:24 +0000 (22:07 +0200)]
build: Fix --with-gcrypt-headers and --with-vorbis-headers.

The configure script sets the autoconf output variable gcrypt_cppflags
according to the configure option --with-gcrypt-headers, but
gcrypt_cppflags is never used for the build.  Hence, if libgcrypt is
installed in a non-standard location, and that location is specified
as the argument to --with-gcrypt-headers, configure detects the gcrypt
header correctly, but the build fails nevertheless.

The same type of bug also exists for the --with-vorbis-headers option.

To fix this omission this patch sets both variables in Makefile.in
and references it in Makefile.real to compile the affected objects
with the correct flags.

9 years agoMerge branch 'refs/heads/t/play_fix'
Andre Noll [Thu, 31 Jul 2014 06:59:47 +0000 (08:59 +0200)]
Merge branch 'refs/heads/t/play_fix'

Cooking since two weeks.

* 9c1aa5 Never start playback at an empty chunk.

Conflicts:
afh_recv.c

9 years agoMerge branch 't/recv_fix'
Andre Noll [Thu, 31 Jul 2014 06:06:21 +0000 (08:06 +0200)]
Merge branch 't/recv_fix'

Cooking for two months.

* t/recv_fix:
  recv: Don't segfault on invalid chunk values.

9 years agoafh_common: Improve documentation of clear_afh().
Andre Noll [Thu, 3 Jul 2014 21:30:58 +0000 (23:30 +0200)]
afh_common: Improve documentation of clear_afh().

The doxygen comment for this public function was rather bad.
This commit changes the comment to clarify that the function does
not free the given afhi structure but only its contents.

9 years agoMerge branch 't/sched_improvements'
Andre Noll [Wed, 23 Jul 2014 15:29:29 +0000 (17:29 +0200)]
Merge branch 't/sched_improvements'

Cooking for two months. This merge required to also patch gui.c due
to semantic conflics against the changes introduced by the gui_sched
branch which was merged to master in commit d15d8509 two weeks ago.
Also a small fix for server.c is needed to squelch a compiler warning
since the global "now" variable has become a const pointer.

* t/sched_improvements: (36 commits)
  audiod: Fix use after free on exit.
  sched: Mark global now pointer as const.
  sched: Directly pass context pointer to pre/post_select().
  sched: kill task->dead.
  sched: Do not shadow task_info in struct task.
  sched: Dont use fixed-size buffer for task names.
  sched: Rename task->error to tast->status.
  sched: Rename task->status to task->name.
  sched: Make struct task private to sched.c.
  sched: Introduce task_status().
  sched: Remove ->owned_by_sched.
  sched: Remove register_task().
  task_register() conversion: grab client task
  task_register() conversion: audiod status task
  task_register() conversion: audiod command task
  task_register() conversion: client task
  task_register() conversion: client supervisor task
  task_register() conversion: client exec task
  task_register() conversion: afs command task
  task_register() conversion: vss task
  ...

9 years agonet.c: Improve documentation of send_cred_buffer() and recv_cred_buffer().
Andre Noll [Mon, 2 Jun 2014 22:01:41 +0000 (00:01 +0200)]
net.c: Improve documentation of send_cred_buffer() and recv_cred_buffer().

Also fix a few whitespace issues while at it.

9 years agoversion.c: Remove bad doxygen \file comment.
Andre Noll [Sat, 12 Jul 2014 12:16:18 +0000 (14:16 +0200)]
version.c: Remove bad doxygen \file comment.

The file is version.h, not version.h.

9 years agoconfigure.ac: Fix list of command line objects for OS X.
Andre Noll [Thu, 10 Jul 2014 19:06:19 +0000 (21:06 +0200)]
configure.ac: Fix list of command line objects for OS X.

The additional .cmdline suffix causes the build to fail.

This bug was introduced 10 months ago in commit 0f4790f2.

9 years agoaudiod: Fix use after free on exit.
Andre Noll [Tue, 15 Jul 2014 05:04:07 +0000 (07:04 +0200)]
audiod: Fix use after free on exit.

client_close() frees the ->ct structure which is used one line later
by task_reap(). valgrind spots this use after free bug and reports

==13497== Invalid read of size 4
==13497==    at 0x8059EA8: task_reap (sched.c:199)
==13497==    by 0x80542FA: close_stat_pipe (audiod.c:1082)
==13497==    by 0x8055632: clean_exit (audiod.c:1159)
==13497==    by 0x80556B6: signal_post_select (audiod.c:1018)
==13497==    by 0x8059E5F: schedule (sched.c:88)
==13497==    by 0x804D41C: main (audiod.c:1437)
==13497==  Address 0x4833c04 is 204 bytes inside a block of size 212 free'd
==13497==    at 0x4028AC0: free (vg_replace_malloc.c:468)
==13497==    by 0x80542E8: close_stat_pipe (audiod.c:1081)
==13497==    by 0x8055632: clean_exit (audiod.c:1159)
==13497==    by 0x80556B6: signal_post_select (audiod.c:1018)
==13497==    by 0x8059E5F: schedule (sched.c:88)
==13497==    by 0x804D41C: main (audiod.c:1437)

The bug was introduced recently in commit 0b43ec5d (task_register()
conversion: client task).

9 years agoMerge branch 't/gui_sched'
Andre Noll [Sun, 13 Jul 2014 14:20:56 +0000 (16:20 +0200)]
Merge branch 't/gui_sched'

Was cooking for two months, since 2014-05-11.

* t/gui_sched: (53 commits)
  gui: Always initialize theme.
  gui: Simplify color handling.
  gui: Dont catch SIGWINCH.
  gui: Call waitpid() from exec and status task.
  Doxify para_gui.
  gui: Speed up window refresh.
  gui: Rename cmd_task to exec_task.
  gui: Move static variables of cmd_post_select() into struct cmd_task.
  gui: Move some variables into struct status_task.
  gui: Switch to the standard paraslash scheduler.
  gui: Use cpp magic to define command handlers.
  gui: Execute stat command in status_post_select().
  gui: Rename COMMAND/EXTERNAL/GETCH mode.
  gui: Get rid of do_select()'s mode parameter and call it only once.
  gui: Reorder functions.
  gui: Move signal handling code out of do_select().
  gui: Move input related code out of do_select().
  gui: Move external command handling out of do_select().
  gui: Introduce status_post_select().
  gui: Improve config reload.
  ...

9 years agoMerge branch 't/cpsi_improvement'
Andre Noll [Thu, 10 Jul 2014 17:53:06 +0000 (19:53 +0200)]
Merge branch 't/cpsi_improvement'

Cooking since 2014-05-03.

* t/cpsi_improvement:
  com_cpsi(): Tell the user if nothing was copied.

9 years agoNever start playback at an empty chunk.
Andre Noll [Sun, 11 May 2014 19:21:15 +0000 (21:21 +0200)]
Never start playback at an empty chunk.

The chunk table of ogg/* audio files often contains "empty" chunks
which correspond to time slices for which the virtual streaming system
does not need to send any data. When playback is started at an empty
chunk, an unnecessary delay results.

To overcome this issue, this commit introduces a new public helper
afh_get_start_chunk() which looks for the first non-empty chunk before
the given chunk number.

The new function is called from afh_recv.c and from vss.c so that
both para_play and para_server now avoid to start streaming at an
empty chunk.

9 years agomanual: Mention that audio format handlers are part
Andre Noll [Fri, 18 Apr 2014 03:20:55 +0000 (03:20 +0000)]
manual: Mention that audio format handlers are part
of para_recv and para_play.

9 years agoerror.h: Remove obsolete RBTREE_ERRORS
Andre Noll [Fri, 18 Apr 2014 01:50:23 +0000 (01:50 +0000)]
error.h: Remove obsolete RBTREE_ERRORS

9 years agoFix two typos in comments of attribute.c.
Andre Noll [Sun, 8 Jun 2014 10:23:52 +0000 (12:23 +0200)]
Fix two typos in comments of attribute.c.

9 years agoMerge branch 't/bitstream_improvements'
Andre Noll [Thu, 26 Jun 2014 16:58:27 +0000 (18:58 +0200)]
Merge branch 't/bitstream_improvements'

Cooking since 2014-04-22.

* t/bitstream_improvements:
  bitstream: Improve documentation.
  wma: Store ASF header info in afhi->techinfo.
  bitstream: Replace check for impossible condition by assertion.
  bitstream: Remove pointless variable "code_prefix2".
  bitstream: Micro-optimization.
  bitstream: Kill pointless variable "symbol".
  bitstream: Trivial coding style fixes.
  bitstream: Trivial spelling fix auxillary -> auxiliary.

9 years agoMerge branch 't/audiod_com_version'
Andre Noll [Thu, 19 Jun 2014 13:39:33 +0000 (15:39 +0200)]
Merge branch 't/audiod_com_version'

Cooking since 2014-04-03.

* t/audiod_com_version:
  audiod: Implement version command.
  audiod: Trival spelling fix for com_tasks().

9 years agocrypt: Simplify base64_decode().
Andre Noll [Mon, 16 Dec 2013 21:58:39 +0000 (22:58 +0100)]
crypt: Simplify base64_decode().

We never call this function with target == NULL.

9 years agosched: Mark global now pointer as const.
Andre Noll [Thu, 9 Jan 2014 17:04:28 +0000 (17:04 +0000)]
sched: Mark global now pointer as const.

The timeval structure pointed to by the public now pointer should not
be modified outside sched.c. Fortunately play.c is the only place
which violates this rule. This patch fixes up play.c and marks the
pointer as const.

9 years agosched: Directly pass context pointer to pre/post_select().
Andre Noll [Thu, 2 Jan 2014 03:24:48 +0000 (03:24 +0000)]
sched: Directly pass context pointer to pre/post_select().

The patch is large, but it's fairly straight forward: Instead of
a task pointer all ->pre_select() and ->post_select() methods now
receive the context pointer that was passed to the scheduler when
the task was registered. This allows to kill the public task_context().

Two pre_select/post_select functions are not directly called by the
scheduler: session_post_select(), generic_recv_pre_select(). These
are changed to receive a proper struct rather than a void pointer.

Note that generic_filter_pre_select() is not changed in this
manner because some filters do not provide a pre_select wrapper but set
task->pre_select to generic_filter_pre_select().

9 years agosched: kill task->dead.
Andre Noll [Thu, 2 Jan 2014 02:07:01 +0000 (02:07 +0000)]
sched: kill task->dead.

The three possible states of a task are determined by the ->status
and ->dead fields of struct task:

status >= 0, !dead: running
status >= 0, dead: dead (about to be removed from the task list)
status < 0: zombie (dead, but not yet reaped, -status is an error code)

This commit encodes the first two states as two non-negative numbers,
so that the three states become

status == TS_RUNNING: running
status == TS_DEAD: dead
status < 0: zombie

This allows to remove ->dead which improves readability somewhat.

9 years agosched: Do not shadow task_info in struct task.
Andre Noll [Thu, 2 Jan 2014 01:43:21 +0000 (01:43 +0000)]
sched: Do not shadow task_info in struct task.

All fields of struct task_info have direct counterparts in struct
task. The fields of struct task are initialized in task_register()
to the corresponding fields of struct task_info. It's easier to
just embed a task_info structure in struct task instead. This also
guarantees that task_register() stays correct in case another field
is added to struct task_info.

9 years agosched: Dont use fixed-size buffer for task names.
Andre Noll [Thu, 2 Jan 2014 01:16:33 +0000 (01:16 +0000)]
sched: Dont use fixed-size buffer for task names.

This is not more complicated than the strncpy(), and it allows for
arbitrary long task names.

9 years agosched: Rename task->error to tast->status.
Andre Noll [Thu, 2 Jan 2014 01:07:11 +0000 (01:07 +0000)]
sched: Rename task->error to tast->status.

We are going to store not only the (negative) error code in this field
of struct task, so status is a better name for it. The conversion is
trivial.

9 years agosched: Rename task->status to task->name.
Andre Noll [Thu, 2 Jan 2014 01:05:54 +0000 (01:05 +0000)]
sched: Rename task->status to task->name.

"status" has always been a misnomer for the user-defined description
of a task. Now that the structure has been made local, only sched.c
needs to be changed.

9 years agosched: Make struct task private to sched.c.
Andre Noll [Wed, 1 Jan 2014 23:36:16 +0000 (23:36 +0000)]
sched: Make struct task private to sched.c.

No direct users of struct sched remain, so we can move the definition
of this structure from sched.h to sched.c.

9 years agosched: Introduce task_status().
Andre Noll [Tue, 31 Dec 2013 17:22:57 +0000 (17:22 +0000)]
sched: Introduce task_status().

Before struct task can be made private to sched.c we must eliminate
code which directly accesses the fields of this structure. The last
offender is ->error: in many places we check this field to detect
whether some task is in an error condition.

This patch provides a public accessor function, task_status(),
for this purpose. All users of ->error are modified to call this
function instead.

9 years agosched: Remove ->owned_by_sched.
Andre Noll [Sat, 1 Mar 2014 11:55:38 +0000 (12:55 +0100)]
sched: Remove ->owned_by_sched.

With register_task() gone, the ->owned_by_sched field of struct sched
is always true (it gets set in task_register()). So we can remove it.

9 years agosched: Remove register_task().
Andre Noll [Thu, 2 Jan 2014 01:01:58 +0000 (01:01 +0000)]
sched: Remove register_task().

Now that all users of this function have been converted to
task_register(), the old function can go away.

9 years agotask_register() conversion: grab client task
Andre Noll [Tue, 31 Dec 2013 00:13:29 +0000 (00:13 +0000)]
task_register() conversion: grab client task

9 years agotask_register() conversion: audiod status task
Andre Noll [Tue, 31 Dec 2013 00:06:28 +0000 (00:06 +0000)]
task_register() conversion: audiod status task

9 years agotask_register() conversion: audiod command task
Andre Noll [Tue, 31 Dec 2013 00:01:12 +0000 (00:01 +0000)]
task_register() conversion: audiod command task

9 years agotask_register() conversion: client task
Andre Noll [Mon, 30 Dec 2013 23:54:26 +0000 (23:54 +0000)]
task_register() conversion: client task

9 years agotask_register() conversion: client supervisor task
Andre Noll [Mon, 30 Dec 2013 23:45:55 +0000 (23:45 +0000)]
task_register() conversion: client supervisor task

9 years agotask_register() conversion: client exec task
Andre Noll [Mon, 30 Dec 2013 23:39:17 +0000 (23:39 +0000)]
task_register() conversion: client exec task

9 years agotask_register() conversion: afs command task
Andre Noll [Mon, 30 Dec 2013 23:34:08 +0000 (23:34 +0000)]
task_register() conversion: afs command task

9 years agotask_register() conversion: vss task
Andre Noll [Mon, 30 Dec 2013 23:30:03 +0000 (23:30 +0000)]
task_register() conversion: vss task

9 years agotask_register() conversion: signal task
Andre Noll [Mon, 30 Dec 2013 23:20:32 +0000 (23:20 +0000)]
task_register() conversion: signal task

9 years agotask_register() conversion: server command task
Andre Noll [Mon, 30 Dec 2013 23:26:00 +0000 (23:26 +0000)]
task_register() conversion: server command task

9 years agotask_register() conversion: play task
Andre Noll [Tue, 15 Apr 2014 13:49:59 +0000 (13:49 +0000)]
task_register() conversion: play task

9 years agotask_register() conversion: writers
Andre Noll [Mon, 30 Dec 2013 22:59:47 +0000 (22:59 +0000)]
task_register() conversion: writers

9 years agotask_register() conversion: write task
Andre Noll [Mon, 30 Dec 2013 22:42:27 +0000 (22:42 +0000)]
task_register() conversion: write task

9 years agotask_register() conversion: i9e task
Andre Noll [Mon, 30 Dec 2013 22:31:08 +0000 (22:31 +0000)]
task_register() conversion: i9e task

9 years agotask_register() conversion: audioc task
Andre Noll [Mon, 30 Dec 2013 22:23:31 +0000 (22:23 +0000)]
task_register() conversion: audioc task

9 years agotask_register() conversion: filter tasks
Andre Noll [Mon, 30 Dec 2013 22:09:38 +0000 (22:09 +0000)]
task_register() conversion: filter tasks

9 years agotask_register() conversion: stdin task
Andre Noll [Wed, 8 Jan 2014 05:16:15 +0000 (05:16 +0000)]
task_register() conversion: stdin task

This renames stdin_set_defaults() to stdin_task_register() and changes
the function to register the stdin task. Before this patch, the task
was registered in the callers.

9 years agotask_register() conversion: receivers
Andre Noll [Sat, 25 Jan 2014 18:41:45 +0000 (19:41 +0100)]
task_register() conversion: receivers

This adds a new public function, task_reap(), to sched.c. It is
called by para_audiod and para_play to free the memory occupied by
the receiver node after EOF. sched_shutdown() can not be used for
this purpose since the scheduler stays active during the life time of
these programs (i.e. schedule() never returns) while receiver nodes
come and go.

The new task_reap() has to face the problem that it is called
from another task's ->post_select() method, so removing the task
being reaped from the scheduler task list is not possible in
task_reap(). Hence this patch adds the new flag "dead" to struct
task. It is initially unset and is turned on in task_reap() to indicate
that (a) the task has exited (i.e. ->post_select() returned negative)
and (b) task_reap() has been called to fetch the exit status. Only
if this flag is set, the scheduler removes the task from the task list.

9 years agosched: Introduce alternative task API.
Andre Noll [Mon, 30 Dec 2013 19:27:04 +0000 (19:27 +0000)]
sched: Introduce alternative task API.

In the current implementation struct task is public so users of this
structure can mess with internal scheduler details as they please. This
has led to many bugs and questionable code in the past. This commit
is the first step to overcome this design mistake. At the end of this
patch series struct task can be made private to sched.c.

This commit introduces the following new public functions:

* task_register,
* task_context,
* sched_shutdown.

It also adds the new public task_info structure which carries the
information passed to the scheduler when a new task is registered. This
structure will stay public while struct task will become private once
all users have been converted.

task_register() is supposed to eventually replace register_task(). The
main difference of the two is that the new function returns a _pointer_
to a task structure which is allocated dynamically. Users are not
supposed to look at the fields of this pointer directly.

task_context() is a temporary helper which can be removed again at the
end of the series. Its sole purpose is to return the context pointer
which was passed at task register time as part of struct task_info.

The final new function, sched_shutdown(), deallocates the task
structures allocated during task_register() to cleanly shut down the
scheduler after all tasks have terminated.

All users need to be converted to the new API. This patch only converts
the stdout task though. The other tasks will be converted in subsequent
patches. The scheduler can tell if a task was registered using the
new API by means of the new ->owned_by_sched bit of struct task.
This boolean variable can also be removed after all tasks have been
converted.

Some users will need to query the exit status of a terminated
task. Hence we keep all tasks on the task list  after ->post_select()
returned negative but call neither ->pre_select() nor ->post_select()
any more for such tasks. This leads to the concept of zombie tasks.

9 years agosched: Mark argument of task_get_notification() as const.
Andre Noll [Tue, 31 Dec 2013 02:15:42 +0000 (02:15 +0000)]
sched: Mark argument of task_get_notification() as const.

We never write to the memory pointed to by the argument.

9 years agoSimplify sched: Use only a single task list.
Andre Noll [Mon, 30 Dec 2013 17:37:41 +0000 (17:37 +0000)]
Simplify sched: Use only a single task list.

Currently the scheduler maintains two linked task lists, the pre_select
and the post_select list. This is completely unnecessary and bloats
the code for no good reason. This patch makes it use a single list
only and updates the documentation accordingly.

9 years agoaudiod: Simplify start_stop_decoders().
Andre Noll [Tue, 31 Dec 2013 12:56:59 +0000 (12:56 +0000)]
audiod: Simplify start_stop_decoders().

open_filters() DTRT if there are no filters configured.
No need to check twice.

9 years agoDon't set t->error in ->pre_select().
Andre Noll [Tue, 31 Dec 2013 17:20:24 +0000 (17:20 +0000)]
Don't set t->error in ->pre_select().

->pre_select() methods should never fail, and tasks should not
set this variable at all. It is ignored anyway when set there.

9 years agoafh_recv: Don't set t->error unnecessarily.
Andre Noll [Tue, 31 Dec 2013 03:22:40 +0000 (03:22 +0000)]
afh_recv: Don't set t->error unnecessarily.

It is always wrong to set t->error directly as this can only confuse
the scheduler.

9 years agoMerge branch 't/ao_fixes'
Andre Noll [Sun, 25 May 2014 13:31:07 +0000 (15:31 +0200)]
Merge branch 't/ao_fixes'

Cooking since 2014-03-22.

* t/ao_fixes:
  ao_write: Call ao_initialize() only once.
  ao_write: Join threads before returning an error from aow_post_select().
  ao_write: Simplify locking.
  Don't unlock and lock the thread mutex unnecessarily.
  ao_write: Check return value of pthread functions.
  ao_write: Avoid segfault on exit.
  ao_write: Avoid pthread_join().
  ao_write: Enforce a 20ms timeout.
  ao_write: Fix spurious segfault.

9 years agogui: Always initialize theme.
Andre Noll [Mon, 12 May 2014 15:51:49 +0000 (17:51 +0200)]
gui: Always initialize theme.

parse_config_file_or_die() contains the following bug: If the
configuration file ~/.paraslash/gui.conf does not exist, the current
code not only skips the gengetopt config file parser (which is correct)
but also omits to call theme_init(), which is incorrect.

The bug was introduced recently in commit 18d37e (Unify config
file parsing). Fix it by moving the call to theme_init() to
the bottom of the function so that it is called if and only if
parse_config_file_or_die() succeeds.

9 years agorecv: Don't segfault on invalid chunk values.
Andre Noll [Sun, 11 May 2014 19:47:03 +0000 (21:47 +0200)]
recv: Don't segfault on invalid chunk values.

If recv->open() fails, para_recv segfaults after

==10129== Conditional jump or move depends on uninitialised value(s)
==10129==    at 0x41BA18A: vfprintf (vfprintf.c:1634)
==10129==    by 0x41BE3D8: buffered_vfprintf (vfprintf.c:2311)
==10129==    by 0x41B975C: vfprintf (vfprintf.c:1289)
==10129==    by 0x804C6AF: stderr_log (in /home/maan/scm/paraslash/para_recv)
==10129==    by 0x804A193: main (recv.c:114)

This happens for example with the afh_receiver if the given start
chunk is bigger than the end chunk, e.g. when para_recv is executed as

./para_recv -r 'afh -b -80 -e -89 -f foo.opus'

The reason for the bug is we zero-out the stdout structure too late.
Fix this by initializing the stdout task structure upfront rather
than using memset().

This bug was introduced a year ago in commit b01605d7 (Avoid unwanted
log messages during startup) which moved down the call to memset().

9 years agoMerge branch 't/test_man'
Andre Noll [Sun, 11 May 2014 10:19:12 +0000 (12:19 +0200)]
Merge branch 't/test_man'

Cooking since 2014-03-16.

* t/test_man:
  test-lib: Make colors work on FreeBSD.
  test suite: Add sanity check for generated man pages.

9 years agogui: Simplify color handling.
Andre Noll [Sat, 8 Mar 2014 20:18:21 +0000 (21:18 +0100)]
gui: Simplify color handling.

Various gui elements of para_gui can be customized through struct
gui_theme. Currently this structure contains two integers for each
each element, one for the foreground and one for the background color
of the element. This is a bit clumsy and repetitive.

This commit cuts down the number of fields of struct gui_theme by
a factor of two by introducing struct gui_color_spec as a pair of
integers.

The patch is quite large but also simple.

9 years agogui: Dont catch SIGWINCH.
Andre Noll [Thu, 13 Feb 2014 18:59:49 +0000 (19:59 +0100)]
gui: Dont catch SIGWINCH.

This is unnecessary since the curses library generates a KEY_RESIZE
event on SIGWINCH anyway. Hence window change events can be handled
as well in the normal input processing function. This allows to remove
the SIGWINCH part of the signal handling code.

Another advantage of handling SIGWINCH in the same way as normal
input events is that it is easier to propagate the event. This will
turn out to be useful for the upcoming gui menu changes.

9 years agogui: Call waitpid() from exec and status task.
Andre Noll [Mon, 27 Jan 2014 10:35:08 +0000 (11:35 +0100)]
gui: Call waitpid() from exec and status task.

This commit changes signal_post_select() to not call waitpid() via
para_reap_child() any more. Instead it notifies all tasks using the
new error code E_GUI_SIGCHLD. The exec task and the status task honor
this notification and call waitpid() for their "own" pid to check
whether the executing process or the stat process has terminated and
to obtain the exit status.

Although neither task cares deeply about the exit code, the menu
commands, which will be implemented in subsequent patches, will
care. So it's good to have the option to get this information.

9 years agoDoxify para_gui.
Andre Noll [Sun, 16 Mar 2014 11:09:01 +0000 (12:09 +0100)]
Doxify para_gui.

Now that para_gui is in a much better shape, let's make it a first
class citizen and document all public functions and data structures.

9 years agogui: Speed up window refresh.
Andre Noll [Mon, 6 Jan 2014 20:12:38 +0000 (20:12 +0000)]
gui: Speed up window refresh.

We had way too many calls to wrefresh() which copies the named
window to the physical terminal screen. This slows down the display
considerably, especially on slow machines.

It is more efficient to perform the copy only once per scheduler
iteration. So this commit adds a flag "needs_update" to struct
gui_window, and all callers to wrefresh() are changed to call
refresh_window() instead. This new function is much cheaper since it
only turns on the needs_update flag but does nothing else.

In input_post_select() we check which windows have the flag set and
repaint those windows using wnoutrefresh() and then doupdate(). This
two-step approach is described in the curs_refresh(3X) man page as
more efficient then calling wrefresh() for each window separately
since it avoids alternating calls to wnoutrefresh() and doupdate().

9 years agogui: Rename cmd_task to exec_task.
Andre Noll [Sat, 4 Jan 2014 22:16:22 +0000 (22:16 +0000)]
gui: Rename cmd_task to exec_task.

The term "command" currently means either a gui command handler or
the process which is executing as a result of a defined key map. Avoid
this confusion by using the word only for command handlers.

This commit also simplifies exec_cmd() and exec_para() slightly by
moving the "hit any key to abort" message into the common function
exec_and_display().

9 years agogui: Move static variables of cmd_post_select() into struct cmd_task.
Andre Noll [Sat, 4 Jan 2014 06:48:36 +0000 (06:48 +0000)]
gui: Move static variables of cmd_post_select() into struct cmd_task.

For the same reason stated in the commit message of the previous patch,
these variables belong to the context structure of the command task,
so move them there.

The COMMAND_BUF_SIZE define had to be moved above the definition of
struct cmd_task since COMMAND_BUF_SIZE uses it.

9 years agogui: Move some variables into struct status_task.
Andre Noll [Sat, 4 Jan 2014 06:32:04 +0000 (06:32 +0000)]
gui: Move some variables into struct status_task.

pre_select and post_select methods should never define static variables
but store their state in the context structure which also contains
the task structure.

This commit moves the static variables of status_post_select() and the
global variables next_exec and stat_pipe into the context structure
of the status task.

9 years agogui: Switch to the standard paraslash scheduler.
Andre Noll [Sat, 4 Jan 2014 06:04:26 +0000 (06:04 +0000)]
gui: Switch to the standard paraslash scheduler.

Due to the preparations performed in previous patches, this is a
rather simple change. Note we don't need to define a struct signal_task
since this structure is already defined in signal.h.

9 years agogui: Use cpp magic to define command handlers.
Andre Noll [Fri, 10 Jan 2014 00:22:07 +0000 (00:22 +0000)]
gui: Use cpp magic to define command handlers.

This shortens the code a bit and avoids duplications. The command
handler for cancel_scroll had to be renamed from com_cancel_scrolling()
to com_cancel_scroll() since the old name did not match command name.

9 years agogui: Execute stat command in status_post_select().
Andre Noll [Sat, 4 Jan 2014 05:38:23 +0000 (05:38 +0000)]
gui: Execute stat command in status_post_select().

pre_select methods should only deal with fd sets and select timeouts,
so the part of status_pre_select() which restarts the status command
belongs to status_post_select().

Unfortunately, after this change both status_pre_select() and
status_post_select() need to know when to restart the stat command.
Therefore we had to add a new global variable next_exec.

The patch also moves status_pre_select() up so that the two functions
are close to each other.

9 years agogui: Rename COMMAND/EXTERNAL/GETCH mode.
Andre Noll [Sat, 29 Mar 2014 17:31:41 +0000 (18:31 +0100)]
gui: Rename COMMAND/EXTERNAL/GETCH mode.

This value tells if there is a command executing, and if so, whether
it is an external command or a display command. Hence "cmd_status"
is to be more to the point.

9 years agogui: Get rid of do_select()'s mode parameter and call it only once.
Andre Noll [Sat, 29 Mar 2014 12:48:03 +0000 (13:48 +0100)]
gui: Get rid of do_select()'s mode parameter and call it only once.

The current code calls do_select() from three different locations. The
mode parameter indicates whether a command is currently running
and if it is a display command or an external command (where curses
is disabled).  This is unnecessarily complex as we can tell from the
values of the command_fd[] array and the cmd_pid variable which mode
we are in.

This commit introduces get_select_mode() which looks at these variables
and returns the current mode. This allows to get rid of the mode
parameter of do_select() and to call do_select() only once at startup
from main(). It now runs in an endless loop, checking the current mode
in each iteration. The other two call sites, exec_and_display_cmd()
and external_cmd(), don't need to call do_select() any more.

This change removes more lines than it adds and makes the logic
of para_gui much simpler to follow. It is also the last big step
to replace the do_select() loop in favor of the standard paraslash
scheduler.

9 years agogui: Reorder functions.
Andre Noll [Sat, 29 Mar 2014 10:34:02 +0000 (11:34 +0100)]
gui: Reorder functions.

As a preparation for the removal of do_select() we need various
functions of gui.c to be in a different order. Specifically,
input_post_select() will soon call handle_command(), so the latter
function will need to be declared before the former.

Patches which move functions around are generally hard to
read, so this commit performs pure code movement only. However,
as exec_and_display_cmd() still calls do_select() we introduce a
temporary forward declaration for do_select(). It will be removed
in the next patch.

9 years agogui: Move signal handling code out of do_select().
Andre Noll [Fri, 3 Jan 2014 19:03:22 +0000 (19:03 +0000)]
gui: Move signal handling code out of do_select().

As a further preparation for employing the standard paraslash scheduler
within para_gui, this simple patch introduces signal_pre_select()
and renames handle_signal() to signal_post_select().

The signal related part of do_select() is moved to these two functions
so that do_select() is reduced to the bare minimum: one call to each
of the two new functions.

9 years agogui: Move input related code out of do_select().
Andre Noll [Fri, 3 Jan 2014 18:49:19 +0000 (18:49 +0000)]
gui: Move input related code out of do_select().

This moves the relevant part of do_select() into the new functions
input_pre_select() and input_post_select().

9 years agogui: Move external command handling out of do_select().
Andre Noll [Fri, 3 Jan 2014 18:16:51 +0000 (18:16 +0000)]
gui: Move external command handling out of do_select().

This commit moves the part of do_select() that deals with
external commands to separate functions, command_pre_select() and
command_post_select().

This change shortens do_select() considerably and is another step
towards the goal of using the paraslash scheduling system also for
para_gui.

One thing to note is that the new command_post_select() returns -1 if
both both fds are closed, i.e. when the currently running command has
terminated. This value gets translated back to zero in do_select(),
preserving the current semantics.

9 years agogui: Introduce status_post_select().
Andre Noll [Sun, 26 Jan 2014 17:14:34 +0000 (18:14 +0100)]
gui: Introduce status_post_select().

This moves stat pipe error handling into read_stat_pipe() and renames
the function to status_post_select(), which is more to the point. It
shortens do_select() a bit.

Since status_post_select() now calls print_all_items() and
clear_all_items() it had to be moved down to avoid a forward
declaration.

9 years agogui: Improve config reload.
Andre Noll [Thu, 13 Mar 2014 08:41:44 +0000 (09:41 +0100)]
gui: Improve config reload.

There are two ways to make para_gui reload its config file: Sending
SIGUSR1 and running the internal reread_conf command. When SIGUSR1
is received, signal_post_select() calls com_reread_conf(). This is
a layer violation since command handlers should only be called from
the input task.

This patch provides the generic function reread_conf() which is called
from both the command handler and from signal_post_select().

9 years agogui: Unify config file parsing.
Andre Noll [Tue, 7 Jan 2014 22:04:21 +0000 (22:04 +0000)]
gui: Unify config file parsing.

The gui config file is parsed on startup, when the reload command
is executed or when SIGUSR1 is received. In all cases we set up a
gengetopt params structure and pass its address to the gengetopt
command line parser.

This commit moves the common code to the new parse_config_file_or_die()
which does the right thing for both the startup and the reload
case. The new function also contains the logic of configfile_exists(),
so this latter function can be removed.

9 years agogui: Remove ->cols and ->lines of struct gui_window.
Andre Noll [Thu, 9 Jan 2014 23:34:11 +0000 (23:34 +0000)]
gui: Remove ->cols and ->lines of struct gui_window.

The curses library provides the getmaxyx() macro to obtain the window
geometry. It's better to use these instead of storing the number of
lines and columns in the gui_window structure because with getmaxyx()
there is no risk to have stale values gui_window structure.

While the ncurses implementation provides getmaxx() and getmaxy()
to get only the number of lines or columns, respectively, only
getmaxyx() is described in the XSI Curses standard. Hence we provide
our own version of the former two functions. These call getmaxyx()
and return one of the two numbers.

With the ->cols and ->lines fields of struct gui_window gone, all
callers had to be adjusted to use either getmaxyx() or one of the
new functions.

9 years agogui: Move call to print_all_items() into init_wins().
Andre Noll [Sun, 26 Jan 2014 19:08:05 +0000 (20:08 +0100)]
gui: Move call to print_all_items() into init_wins().

All three callers of init_wins() called print_all_items() directly
thereafter. init_wins() had to be moved below print_all_items().

9 years agogui: Improve check_key_map_args().
Andre Noll [Tue, 7 Jan 2014 18:52:26 +0000 (18:52 +0000)]
gui: Improve check_key_map_args().

Simplify the code a bit, make it call die() on errors and print
the invalid key map in the error case.

9 years agogui: Combine exit functions.
Andre Noll [Tue, 7 Jan 2014 17:35:08 +0000 (17:35 +0000)]
gui: Combine exit functions.

Currently we have kill_pg_and_die(), finish(), msg_n_exit(), which
is kind of excessive. This patch replaces these three functions by
the single die() which does the right thing in all cases.

9 years agogui: Make curses_log() work also when curses is not active.
Andre Noll [Tue, 7 Jan 2014 16:55:32 +0000 (16:55 +0000)]
gui: Make curses_log() work also when curses is not active.

This allows to get rid of all fprintf(stderr, ...) constructs and
simplifies the code a bit.

9 years agogui: Parse command line options only once.
Andre Noll [Tue, 7 Jan 2014 15:59:27 +0000 (15:59 +0000)]
gui: Parse command line options only once.

There is no point in calling gui_cmdline_parser_ext() when rereading
the configuration since this parser only looks at the command line
options which never change.

Removing the call in com_reread_conf() also allows to get rid of the
global _argc and _argv variables.

9 years agogui: Clear top window only once on resize.
Andre Noll [Mon, 6 Jan 2014 18:08:16 +0000 (18:08 +0000)]
gui: Clear top window only once on resize.

init_wins() already clears the top window.

9 years agogui: Replace global variable curses_active by a function.
Andre Noll [Sun, 5 Jan 2014 20:48:29 +0000 (20:48 +0000)]
gui: Replace global variable curses_active by a function.

There is no need to store this information as we can easily compute it.

shutdown_curses() needed to be changed to cope with early failures:
On fatal errors that happen after initscr() was called but before
the top window exists, we must shut down the curses subsystem albeit
curses_active() returns false in this case.

9 years agogui: Kill struct gui_window->beg{xy}.
Andre Noll [Mon, 6 Jan 2014 16:11:56 +0000 (16:11 +0000)]
gui: Kill struct gui_window->beg{xy}.

These values are only needed in init_wins(), so we might as well use
local variables for them.

9 years agogui: Remove change_theme().
Andre Noll [Tue, 7 Jan 2014 22:08:00 +0000 (22:08 +0000)]
gui: Remove change_theme().

It's silly to have a function for this.

9 years agogui: Move windows *after* resizing them.
Andre Noll [Sun, 26 Jan 2014 19:18:00 +0000 (20:18 +0100)]
gui: Move windows *after* resizing them.

This appeared to be the reason why refresh() was needed twice.

9 years agogui: Rename public gui theme functions.
Andre Noll [Tue, 7 Jan 2014 00:40:20 +0000 (00:40 +0000)]
gui: Rename public gui theme functions.

Prefix all functions related to themes with "theme_".

9 years agoRemove chop().
Andre Noll [Tue, 7 Jan 2014 00:25:38 +0000 (00:25 +0000)]
Remove chop().

In curses_log() we currently we call chop(), which calls strlen()
to find the last character of the given string. This is unnecessary
since xvasprintf() returns this information anyway, we just have to
remember it.

With this change the last user of chop() is gone, so this patch
removes chop() from string.c.

9 years agogui: Use whline() for drawing the separator.
Andre Noll [Mon, 6 Jan 2014 02:45:28 +0000 (02:45 +0000)]
gui: Use whline() for drawing the separator.

This should be slightly more efficient.

This patch also changes the type of struct gui_theme->sep_str from
const char * to plain char and renames the field to sep_char. It must
be a single-character string anyway.

For the colorful blackness theme we now use the default character
from curses.h rather than '-'. This looks nicer. Tested with ncurses
on Linux and the curses implementation that ships with NetBSD.

9 years agogui: Remove welcome message.
Andre Noll [Tue, 7 Jan 2014 19:20:13 +0000 (19:20 +0000)]
gui: Remove welcome message.

The only information shown by print_welcome() that is not already
contained in the status bar is the name of the current theme. This
is not very interesting, so remove the function and the corresponding
color pair.

9 years agogui: Simplify print_status_bar().
Andre Noll [Sun, 26 Jan 2014 17:39:56 +0000 (18:39 +0100)]
gui: Simplify print_status_bar().

Curses is always active at this point, so remove the check. Moreover,
refreshing of all other windows is performed in init_wins(), so move
the call to wrefresh() there to be consistent. Finally, the comment
of this function is rather pointless, so remove that as well.

9 years agogui: Print the status bar only once.
Andre Noll [Mon, 6 Jan 2014 17:56:20 +0000 (17:56 +0000)]
gui: Print the status bar only once.

Currently we print it twice on startup. Remove the redundant call
to print_status_bar().

9 years agogui: Remove macro STANDARD_STATUS_BAR.
Andre Noll [Sun, 5 Jan 2014 05:03:32 +0000 (05:03 +0000)]
gui: Remove macro STANDARD_STATUS_BAR.

It's only referenced once in print_status_bar(), so we may as well
print the text there without defining a macro for it.

9 years agogui: Simplify display command execution.
Andre Noll [Fri, 3 Jan 2014 20:58:24 +0000 (20:58 +0000)]
gui: Simplify display command execution.

para_cmd() and display_cmd() are almost identical. Move the
command part into send_output() and rename this function to
exec_and_display_cmd().