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

pictures.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 "globals.h"
#include "pictures.h"
#include "brandom.h"
#include "pbar.h"


Pictures_t *pictures = NULL;


static int
Pictures_compare(const void *_a, const void *_b)
{
  Picture8_t **a = (Picture8_t **)_a;
  Picture8_t **b = (Picture8_t **)_b;

  assert(*a != NULL);
  assert(*b != NULL);
  assert((*a)->dname != NULL);
  assert((*b)->dname != NULL);

  return strcasecmp((*a)->dname, (*b)->dname);
}


void
Pictures_new(const char *basedir, const char *themes)
{
  DIR *dir;
  struct dirent *entry;
  GSList *tmp = NULL;
  u_short size = 0;
  GSList *t;
  PBar_t *pb = NULL;
  gchar **tokens, **theme;

  assert(basedir != NULL);
  assert(themes != NULL);

  if (libbiniou_verbose)
    pb = pbar_new();

  tokens = g_strsplit(themes, ",", 0);
  theme = tokens;

  for ( ; *theme != NULL; theme++) {
    char *directoryname;
    char *th = *theme;

    printf("[+] Loading theme '%s': ", th);
    fflush(stdout);
    if (*th == '~') {
      th++;
      if (*th != '\0')
      directoryname = g_strdup_printf("%s/." PACKAGE_NAME "/images/%s", g_get_home_dir(), th);
      else {
      fprintf(stderr, "[!] Not a valid tilde-theme: %s\n", *theme);
      continue;
      }
    } else
      directoryname = g_strdup_printf("%s/%s", basedir, *theme);

    dir = opendir(directoryname);
    if (dir == NULL) {
      fprintf(stderr, "[!] Error while reading picture directory %s content: %s\n",
            directoryname, strerror(errno));
      g_free(directoryname);
      continue;
    }

    while ((entry = readdir(dir)) != NULL) {
      long hash;
      Picture8_t *pic;

      if (entry->d_name[0] == '.')
      continue;

      pic = Picture8_new();
      hash = FNV_hash(entry->d_name);

      if (Picture8_load(pic, hash, directoryname,
                  entry->d_name) != 0) {
      Picture8_delete(pic);
      continue;
      }

      tmp = g_slist_prepend(tmp, (gpointer)pic);
      size++;

      if (libbiniou_verbose && !(size % 5))
      pbar_step(pb);

      for (t = g_slist_next(tmp);
         t != NULL;
         t = g_slist_next(t))
      if (((Picture8_t *)t->data)->id == hash)
        xerror("Duplicated picture hash: %s / %s, %li\n",
             ((Picture8_t *)t->data)->name, entry->d_name, hash);
    }
    if (closedir(dir) == -1)
      xperror("closedir");
    g_free(directoryname);
    printf("done.\n");
  }

  g_strfreev(tokens);

  pictures = xmalloc(sizeof(Pictures_t));
  if (libbiniou_verbose) {
    pbar_delete(pb);
    printf("[p] Loaded %d pictures\n", size);
  }

  if (size) {
    u_short i;

    pictures->pics = xmalloc(size*sizeof(Picture8_t *));
    for (i = 0, t = tmp;
       t != NULL;
       t = g_slist_next(t), i++) {
      pictures->pics[i] = (Picture8_t *)t->data;
    }
    g_slist_free(tmp);
    pictures->size = size;

    qsort((void *)pictures->pics, (size_t)pictures->size, 
        (size_t)sizeof(Picture8_t *), &Pictures_compare);

  } else {
    xfree(pictures);
  }
}


void
Pictures_delete()
{
  if (pictures != NULL) {
    u_short i;

    for (i = 0; i < pictures->size; i++)
      Picture8_delete(pictures->pics[i]);
    xfree(pictures->pics);
    xfree(pictures);
  }
}


const char *
Pictures_name(const long id)
{
  u_short i;
  
  if (pictures == NULL) {
    printf("[!] No pictures loaded\n");
    return NULL;
  }
  
  for (i = 0; i < pictures->size; i++)
    if (pictures->pics[i]->id == id)
      return pictures->pics[i]->dname;

  if (id == 0)
    return pictures->pics[0]->dname;

  printf("[!] Pictures_name: id %li not found\n", id);

  return NULL;
}


int
Pictures_index(const long id)
{
  u_short i;
  
  if (pictures == NULL) {
    printf("[!] No pictures loaded\n");
    return -1;
  }
  
  for (i = 0; i < pictures->size; i++)
    if (pictures->pics[i]->id == id)
      return i;

  printf("[!] Pictures_index: id %li not found\n", id);

  return -1;
}


long
Pictures_find(const char *name)
{
  u_short i;

  if (pictures == NULL) {
    printf("[!] No pictures loaded\n");
    return -1;
  }
  
  for (i = 0; i < pictures->size; i++)
    if (!strcmp(pictures->pics[i]->dname, name))
      return pictures->pics[i]->id;

  printf("[!] Picture '%s' not found\n", name);
  return pictures->pics[0]->id; /* Use the first picture by default */
}


long
Pictures_random_id()
{
  u_long idx;

  assert(pictures != NULL);
  idx = b_rand_int_range(0, pictures->size-1);

  return pictures->pics[idx]->id;
}


const Picture8_t *
Pictures_random()
{
  u_long idx;

  assert(pictures != NULL);
  idx = b_rand_int_range(0, pictures->size-1);

  return pictures->pics[idx];
}

Generated by  Doxygen 1.6.0   Back to index