Logo Search packages:      
Sourcecode: lebiniou version File versions  Download package

biniou.c

/*
 *  Copyright 1994-2011 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "biniou.h"
#include "sequence.h"
#include "brandom.h"
#include "globals.h"
#include "pictures.h"
#include "colormaps.h"
#include "pnglite.h"

#define VERBOSE(X) if (libbiniou_verbose) X


static void
exit_if_r00t()
{
  uid_t uid = getuid();

  if (0 == uid) {
    fprintf(stderr, "You do not run programs linked against the biniou library\n"
          "with root privileges, do you ?\n");
    exit(1);
  }
}


void
biniou_new(const char *datadir, const char *pluginsdir,
         const char *schemes, const char *themes,
         const u_short width, const u_short height,
         const u_char options)
{
  char *buf;

  exit_if_r00t();

  if (options & B_INIT_VERBOSE)
    libbiniou_verbose = 1;

  WIDTH = width;
  HEIGHT = height;

  /* PRNG */
  b_rand_init();

  /* pnglite */
  png_init((png_alloc_t)0, (png_free_t)0);

  if (datadir != NULL) {
    /* Pictures */
    buf = g_strdup_printf("%s/images/", datadir);
    VERBOSE(
#ifdef XDEBUG
      printf("[+] Loading pictures from %s\n", buf)
#else
      printf("[+] Loading pictures\n")
#endif
      );
    Pictures_new(buf, themes);
    g_free(buf);
        
    /* Colormaps */
    buf = g_strdup_printf("%s/colormaps/", datadir);
    VERBOSE (
#ifdef XDEBUG
      printf("[+] Loading colormaps from %s: ", buf)
#else
      printf("[+] Loading colormaps: ")
#endif
      );
    Colormaps_new(buf);
    g_free(buf);
  } else {
    Colormaps_new(NULL);
  }

  /* Schemes */
  if (options & B_INIT_SCHEMES) {
    VERBOSE(printf("[+] Loading schemes from %s\n", schemes));
    Schemes_new(schemes);
  } else {
    VERBOSE(printf("[+] Creating default scheme\n"));
    Schemes_new_default();
  }

  /* Context */
  context = Context_new();

  /* Plugins */
  VERBOSE(printf("[+] Loading plugins\n"));
  plugins = Plugins_new(pluginsdir);
  Plugins_load(plugins);

  /* Sequences */
  if (options & B_INIT_SEQUENCES) {
    VERBOSE(printf("[+] Loading sequences\n"));
    Sequences_new();
  }

  VERBOSE(printf("[+] Biniou initialized\n"));
}


/*!
 * Starts the biniou
 */
void
biniou_start()
{
  GSList *outputs = context->outputs;

  Plugins_init(plugins);

  if ((sequences == NULL) || !sequences->size) {
    /* Random boot sequence */
    VERBOSE(printf("[i] No user sequences found\n"));
    Schemes_random(context);
  } else {
    GList *prout;
    Sequence_t *first;

    context->sm->curseq = prout = g_list_first(sequences->seqs);
    first = (Sequence_t *)prout->data;

    Sequence_copy(first, context->sm->next);
    Shuffler_used(sequences->shuffler, 0);
  }

  assert(context->sm->cur != NULL);
  assert(context->sm->new != NULL);
  Context_set(context);

  /* XXX */
  for ( ; outputs != NULL; outputs = g_slist_next(outputs)) {
    Plugin_t *output = (Plugin_t *)outputs->data;
    if (output->fullscreen != NULL)
      output->fullscreen(context->fullscreen);
  }
}


void
biniou_delete()
{
  VERBOSE(printf("[+] Freeing PRNG\n"));
  b_rand_free();

  VERBOSE(printf("[+] Freeing context\n"));
  Context_delete(context);
}


void
biniou_end()
{
  if (NULL == context)
    xerror("biniou_end() called but context is NULL\n");
  else
    context->running = 0; /* This will stop plugins running as threads */

  if (pictures != NULL) {
    VERBOSE(printf("[+] Freeing %d picture(s)\n", pictures->size));
    Pictures_delete(pictures);
  }

  if (colormaps != NULL) {
    VERBOSE(printf("[+] Freeing %d colormap(s)\n", colormaps->size));
    Colormaps_delete(colormaps);
  }

  /* TODO %d schemes as above */
  VERBOSE(printf("[+] Freeing schemes\n"));
  Schemes_delete();

  /* TODO %d sequences as above */
  VERBOSE(printf("[+] Freeing sequences\n"));
  Sequences_free();

  /* TODO %d plugins as above */
  VERBOSE(printf("[+] Freeing plugins\n"));
  Plugins_delete(plugins);
}


void
biniou_loop()
{
  biniou_go(0, 1);
}


void
biniou_run()
{
  biniou_start();
  biniou_loop();
}


int
biniou_stop()
{
  if (context == NULL)
    return 0;

  context->running = 0;
  return 1;
}


void
biniou_load_input(const char *dir, const char *name)
{
  Plugin_t *p;

  p = Plugin_new(dir, name, PL_INPUT);
  Plugin_init(p);
  context->input_plugin = p;
}


void
biniou_set_input(Input_t *input)
{
  assert(NULL != context);
  context->input = input;
}


void
biniou_load_output(const char *dir, const char *name)
{
  Plugin_t *p;
  gchar **tokens, **output;
  
  assert(NULL != context);

  tokens = g_strsplit(name, ",", 0);
  output = tokens;

  for ( ; *output != NULL; output++) {
    p = Plugin_new(dir, *output, PL_OUTPUT);
    Plugin_init(p);
    context->outputs = g_slist_prepend(context->outputs, p);
  }

  g_strfreev(tokens);
}


void
biniou_set_full_screen(const u_char full_screen)
{
  assert(NULL != context);
  context->fullscreen = full_screen;
}


void
biniou_set_max_fps(const u_short fps)
{
  Context_set_max_fps(context, fps);
}


void
biniou_verbosity(const u_char v)
{
  libbiniou_verbose = v;
}


void
biniou_set_random_mode(const enum RandomMode r)
{
  Context_set_random_mode(context, r);
}


void
biniou_set_osd_mode(const enum OSDMode m)
{
  Context_set_osd_mode(context, m);
}


void
biniou_go(const u_long nb_frames, const u_char exit)
{
  u_long frames = nb_frames;
  
  while (context->running && ((nb_frames == 0) || frames)) {
    Context_run(context);
    
    if (nb_frames != 0) {
      frames--;
      if (!frames && exit)
      context->running = 0;
    }
  }
  
  /* LA FIIIIIN DU MOOOOOOONDE! *DONG* *DONG* */
  /* XXX move this outside,
     a program will have to do:
     biniou_start();
     biniou_go(N);
     biniou_end(); -> will have to do context->running = 0;
  */
  if (exit)
    biniou_end();
}


void
biniou_set_events_cb(void (*f)(Context_t *ctx, const BKey_t *key))
{
  assert(NULL != context);
  context->events_cb = f;
}

Generated by  Doxygen 1.6.0   Back to index