Logo Search packages:      
Sourcecode: matchbox-desktop version File versions  Download package

mbdesktop_item.c

#include "mbdesktop_item.h"
#include "mbdesktop_module.h"
#include "md5.h"

#define WARN(txt) fprintf(stderr, "%s:%i %s %s", __FILE__, __LINE__, __func__, txt )

static char*
md5sum(char *str)
{
  md5_state_t state;
  md5_byte_t digest[16];
  char *hex_output = (char *)malloc(sizeof(char)*((16*2) + 1));
  int di;

  md5_init(&state);
  md5_append(&state, (const md5_byte_t *)str, strlen(str));
  md5_finish(&state, digest);

  for (di = 0; di < 16; ++di)
    sprintf(hex_output + di * 2, "%02x", digest[di]);

  return hex_output;
}

MBDesktopItem *
mbdesktop_item_new()
{
  MBDesktopItem *ditem;
  ditem = malloc(sizeof(MBDesktopItem));
  memset(ditem, 0, sizeof(MBDesktopItem));
  
  ditem->type = ITEM_TYPE_UNKNOWN;

  return ditem;
}

void
mbdesktop_item_free(MBDesktop     *mb, 
                MBDesktopItem *item)
{
  /* XXX callback to free item->data */

  if (item->name)      free(item->name);
  if (item->name_extended)      free(item->name_extended);
  if (item->icon_name) free(item->icon_name);
  if (item->icon)      mb_pixbuf_img_free(mb->pixbuf, item->icon);

  /* XXX check for children to free ? */

  free(item);

}

MBDesktopItem*
mbdesktop_item_folder_get_open(MBDesktop     *mb) 
{
  return mb->current_folder_item;
}

MBDesktopItem*
mbdesktop_item_folder_set_view(MBDesktop     *mb,
                         MBDesktopItem *folder,
                         int            view) 
{
  folder->view = view;
  return folder;        /* XXX ? */
}

int
mbdesktop_item_folder_get_view(MBDesktop     *mb,
                         MBDesktopItem *folder) 
{
  return folder->view;  
}

Bool
mbdesktop_item_is_folder (MBDesktop *mb, MBDesktopItem *item)     
{
  return (item->type == ITEM_TYPE_FOLDER 
        || item->type == ITEM_TYPE_ROOT
        || item->type == ITEM_TYPE_PREVIOUS);
}


Bool
mbdesktop_item_folder_has_contents(MBDesktop     *mb, 
                           MBDesktopItem *folder)
{
  if (folder->item_child && folder->item_child->item_next_sibling)
    return True;
  return False;
}

void
mbdesktop_item_folder_contents_free(MBDesktop     *mb, 
                            MBDesktopItem *item)
{
  MBDesktopItem *item_tmp = NULL, *item_cur = NULL;

  if (item->item_child && item->item_child->item_next_sibling)
    {
      if (item == mb->top_head_item )
      {
        item_cur = item->item_child;
        mb->top_head_item->item_child = NULL;
      }
      else item_cur = item->item_child->item_next_sibling;

      while (item_cur != NULL)
      {
        item_tmp = item_cur->item_next_sibling;

        /* XXX free up any children - check this !! XX */
        if (item_cur->item_child)
          mbdesktop_item_folder_contents_free(mb, item_cur->item_child);

        /* Stop possible segv of focus_item pointing to non-existant */
        if (mb->kbd_focus_item == item_cur)
          mb->kbd_focus_item = item->item_child;

        mbdesktop_item_free(mb, item_cur); 
        item_cur = item_tmp;
      }
      if ( item != mb->top_head_item)
      item->item_child->item_next_sibling = NULL;
    }
}

MBDesktopItem *
mbdesktop_item_new_with_params (MBDesktop     *mb,
                          const char    *name, 
                          const char    *icon_name,
                          void          *data,
                          int            type)
{
  MBDesktopItem *ditem;
  ditem = mbdesktop_item_new();

  if (name) ditem->name           = strdup(name);
  if (icon_name)
    {
      if (strlen(icon_name) > 5
        && icon_name[strlen(icon_name)-4] != '.'
        && icon_name[strlen(icon_name)-5] != '.')
      {
        /* Tag .png onto the end of icon names with appear 
           to have no extension.                            */
        ditem->icon_name = malloc(sizeof(char)*(strlen(icon_name)+5));
        sprintf(ditem->icon_name, "%s.png", icon_name); 
      }
      else
      {
        ditem->icon_name = strdup(icon_name);
      }
    }

  mbdesktop_item_set_icon_from_theme(mb, ditem);

  if (data) ditem->data           = data;

  /*
  if (exec_str) ditem->exec_str   = strdup(exec_str);
  if (exec_cb) ditem->exec_cb     = exec_cb;
  if (populate_cb) ditem->populate_cb  = populate_cb;
  */

  if (type) ditem->type           = type;

  ditem->view = VIEW_ICONS;

  return ditem;
}

void
mbdesktop_item_set_icon_from_theme (MBDesktop     *mb,
                            MBDesktopItem *item)
{
#ifdef MB_HAVE_PNG
  char *default_icon_name = "mbnoapp.png";
#else
  char *default_icon_name = "mbnoapp.xpm";
#endif

  char *icon_path = NULL;
  icon_path = mb_dot_desktop_icon_get_full_path (mb->theme_name, 
                                     mb->icon_size, 
                                     item->icon_name);

  if (icon_path == NULL)
    icon_path = mb_dot_desktop_icon_get_full_path (mb->theme_name, 
                                       mb->icon_size, 
                                       default_icon_name);

  if (icon_path == NULL)      /* Still NULL, something is wrong */
    {
      fprintf(stderr, "matchbox-desktop: could not load default icon. Is matchbox-common installed ?\n"); 
      exit(1); 
    }


  if (item->icon) mb_pixbuf_img_free(mb->pixbuf, item->icon);

  if ((item->icon = mb_pixbuf_img_new_from_file(mb->pixbuf, icon_path)) 
      == NULL)
    {
      fprintf(stderr, "matchbox-desktop: could not load %s for %s\n", 
            icon_path, item->name);
      /* exit(1); */
    }

  if (icon_path) free(icon_path);

  return;
}

void
mbdesktop_items_append (MBDesktop     *mb,
                  MBDesktopItem *item_head,
                  MBDesktopItem *item )
{
  MBDesktopItem *item_tmp = NULL;

  item_tmp = item_head;

  while ( item_tmp->item_next_sibling != NULL )
    item_tmp = item_tmp->item_next_sibling;

  item_tmp->item_next_sibling = item;
  item->item_prev_sibling = item_tmp;

}

void
mbdesktop_items_insert_after (MBDesktop     *mb,
                        MBDesktopItem *suffix_item,
                        MBDesktopItem *item )
{
  if (!suffix_item->item_next_sibling)
    {
      mbdesktop_items_append (mb, suffix_item, item);
      return;
    }

  item->item_next_sibling = suffix_item->item_next_sibling;

  suffix_item->item_next_sibling->item_prev_sibling = item;

  suffix_item->item_next_sibling = item;

  item->item_prev_sibling = suffix_item;  
}

void
mbdesktop_items_append_to_folder (MBDesktop      *mb,
                          MBDesktopItem  *item_folder,
                          MBDesktopItem  *item )
{
  /* -- need to fix this warning --
  if (item_folder->type != ITEM_TYPE_FOLDER && item->type != ITEM_TYPE_ROOT)
    WARN("Passed folder item is not folder\n");
  */

  if (!item_folder->item_child) return;

  item->module_handle = item_folder->module_handle;

  mbdesktop_items_append (mb, item_folder->item_child, item);

}

void
mbdesktop_items_append_to_top_level (MBDesktop      *mb,
                             MBDesktopItem  *item )
{
  MBDesktopItem *top_level = mbdesktop_get_top_level_folder(mb);

  /* item->module_handle = item_folder->module_handle; ???  */ 

  item->item_parent = top_level;

  if (top_level->item_child == NULL)
    top_level->item_child = item;
  else
    mbdesktop_items_append (mb, top_level->item_child, item); 
}

void
mbdesktop_items_prepend (MBDesktop      *mb,
                   MBDesktopItem **item_head,
                   MBDesktopItem  *item )
{
  MBDesktopItem *item_tmp = NULL;

  /*
  if ((*item_head)->type == ITEM_TYPE_PREVIOUS)
    item_tmp = (*item_head)->item_next_sibling;
  else
  */

  item_tmp = *item_head;
  item->item_next_sibling = item_tmp;
  item_tmp->item_prev_sibling = item;

  *item_head = item;


}

MBDesktopItem *
mbdesktop_item_get_next_sibling(MBDesktopItem *item)
{
  return item->item_next_sibling;
}

MBDesktopItem *
mbdesktop_item_get_prev_sibling(MBDesktopItem *item)
{
  return item->item_prev_sibling;
}

MBDesktopItem *
mbdesktop_item_get_parent(MBDesktopItem *item)
{
  MBDesktopItem *result = mbdesktop_item_get_first_sibling(item);

  if (result && result->item_parent)
    return result->item_parent;

  return NULL;
}

MBDesktopItem *
mbdesktop_item_get_child(MBDesktopItem *item)
{
  /* XXX Need to fix warnings
  if (item->type != ITEM_TYPE_FOLDER && item->type != ITEM_TYPE_ROOT)
    WARN("Passed folder item is not folder\n");
  */

  return item->item_child;
}


MBDesktopItem *
mbdesktop_item_get_first_sibling(MBDesktopItem *item)
{
  while (item->item_prev_sibling != NULL )
    item = item->item_prev_sibling;
  return item;
}

MBDesktopItem *
mbdesktop_item_get_last_sibling(MBDesktopItem *item)
{
  while (item->item_next_sibling != NULL )
    item = item->item_next_sibling;
  return item;
}

void
mbdesktop_item_set_icon_data (MBDesktop     *mb, 
                        MBDesktopItem *item, 
                        MBPixbufImage *img)
{
  if (item->icon) mb_pixbuf_img_free(mb->pixbuf, item->icon);
  item->icon = mb_pixbuf_img_clone(mb->pixbuf, img);
}

void
mbdesktop_item_set_name (MBDesktop     *mb, 
                   MBDesktopItem *item, 
                   char          *name)
{
  if (item->name) free(item->name);
  item->name = strdup(name);
}

char *
mbdesktop_item_get_name (MBDesktop     *mb, 
                   MBDesktopItem *item)
{
  return item->name;
}

void
mbdesktop_item_set_comment (MBDesktop     *mb, 
                      MBDesktopItem *item, 
                      char          *comment)
{
  if (item->comment) free(item->comment);
  item->comment = strdup(comment);
}

char *
mbdesktop_item_get_comment (MBDesktop     *mb, 
                      MBDesktopItem *item)
{
  return item->comment;
}


void
mbdesktop_item_set_extended_name (MBDesktop     *mb, 
                               MBDesktopItem *item, 
                               char          *name)
{
  if (item->name_extended) free(item->name_extended);
  item->name_extended = strdup(name);
}

char *
mbdesktop_item_get_extended_name (MBDesktop     *mb, 
                          MBDesktopItem *item)
{
  return item->name_extended;
}

void
mbdesktop_item_set_user_data (MBDesktop     *mb, 
                        MBDesktopItem *item, 
                        void          *data)
{
  if (item->data) free(item->data); /* XXX callback ? */
  item->data = data;
}

void *
mbdesktop_item_get_user_data (MBDesktop     *mb, 
                        MBDesktopItem *item)
{
  return item->data;
}


void
mbdesktop_item_set_image (MBDesktop     *mb, 
                    MBDesktopItem *item, 
                    char          *full_img_path)
{
  if (item->icon) mb_pixbuf_img_free(mb->pixbuf, item->icon);
  item->icon = mb_pixbuf_img_new_from_file(mb->pixbuf, full_img_path);

  if (item->icon == NULL)
    fprintf(stderr, "matchbox-desktop: *warning* failed to load '%s' \n",
          full_img_path);
}

void
mbdesktop_item_set_activate_callback (MBDesktop     *mb, 
                              MBDesktopItem *item, 
                              MBDesktopCB    activate_cb)
{
  item->activate_cb = activate_cb;
}

void
mbdesktop_item_set_type (MBDesktop     *mb, 
                   MBDesktopItem *item,
                   int            type)
{
  item->subtype = type;
}

int
mbdesktop_item_get_type (MBDesktop     *mb, 
                   MBDesktopItem *item)
{
  return item->subtype;
}

void
mbdesktop_item_cache (MBDesktop     *mb, 
                  MBDesktopItem *item,
                  char          *ident )
{
  struct stat st;
  gzFile cachefile;
  char path[1024];
  char new_ident[1024];
  char *md5 = NULL;
  int name_len = 0, name_e_len =0, comment_len = 0;

  snprintf(new_ident, 1024, "%s-%i", ident, mb->icon_size);
  
  md5 = md5sum(new_ident);

  snprintf(path, 1024, "%s/.thumbnails", mb_util_get_homedir());
  
  /* Check if ~/.matchbox exists and create if not */
  if (stat(path, &st) != 0)
      mkdir(path, 0755);

  snprintf(path, 1024, "%s/.thumbnails/%s", mb_util_get_homedir(), md5);
  
  if ((cachefile = gzopen (path, "wb")) == NULL )
    {
      fprintf(stderr, "%s() failed to open : %s", __func__, path);
      free(md5);
      return;
    }

  name_len = item->name != NULL ? strlen(item->name) : 0;
  name_e_len = item->name_extended != NULL ? strlen(item->name_extended) : 0;
  comment_len = item->comment != NULL ? strlen(item->comment) : 0;

  gzwrite (cachefile, (void *)&name_len, sizeof(int));
  gzwrite (cachefile, (void *)&name_e_len, sizeof(int));
  gzwrite (cachefile, (void *)&comment_len, sizeof(int));

  if (item->name)
    gzwrite (cachefile, (void *)item->name, 
           strlen(item->name));

  if (item->name_extended)
    gzwrite (cachefile, (void *)item->name_extended, 
           strlen(item->name_extended));

  if (item->comment)
    gzwrite (cachefile, (void *)item->comment, 
           strlen(item->comment));

  gzwrite (cachefile, (void *)&item->icon->width, sizeof(int)); 
  gzwrite (cachefile, (void *)&item->icon->height, sizeof(int)); 
  gzwrite (cachefile, (void *)&item->icon->has_alpha, sizeof(int)); 
  gzwrite (cachefile, (void *)item->icon->rgba, 
         item->icon->width * item->icon->height * ( 3 + item->icon->has_alpha));
  gzclose (cachefile);
  free(md5);

}

MBDesktopItem *
mbdesktop_item_from_cache (MBDesktop *mb, 
                     char      *ident,
                     time_t     age)
{
  MBDesktopItem *item;
  char path[1024];
  char new_ident[1024];
  char *md5 = NULL;
  char buf[1024];           
  struct stat stat_info;
  gzFile cache_file;
  int name_len = 0, name_e_len =0, comment_len = 0;
  int img_w, img_h, has_alpha;
  unsigned char *img_data = NULL, *tmp_ptr = NULL;

  snprintf(new_ident, 1024, "%s-%i", ident, mb->icon_size);

  md5 = md5sum(new_ident);

  snprintf(path, 1024, "%s/.thumbnails/%s", mb_util_get_homedir(), md5);

  if (stat(path, &stat_info) == -1) 
    return NULL;

  if (age > stat_info.st_mtime)
    return NULL;

  cache_file = gzopen (path, "rb");

  gzread (cache_file, (void *)&name_len, sizeof(int));
  gzread (cache_file, (void *)&name_e_len, sizeof(int));
  gzread (cache_file, (void *)&comment_len, sizeof(int));

  item = mbdesktop_item_new();

  item->type = ITEM_TYPE_MODULE_ITEM;

  if (name_len)
    {
      gzread (cache_file, (void *)buf, name_len);
      buf[name_len] = '\0';
      item->name = strdup(buf);
      printf("cache gives %s\n", item->name);
    }

  if (name_e_len)
    {
      gzread (cache_file, (void *)buf, name_e_len);
      buf[name_e_len] = '\0';
      item->name_extended = strdup(buf);
      printf("cache gives %s\n", item->name_extended);
    }

  if (comment_len)
    {
      gzread (cache_file, (void *)buf, comment_len);
      buf[comment_len] = '\0';
      item->comment = strdup(buf);
      printf("cache gives %s\n", item->comment);
    }
  
  gzread (cache_file, (void *)&img_w, sizeof(int));
  gzread (cache_file, (void *)&img_h, sizeof(int));
  gzread (cache_file, (void *)&has_alpha, sizeof(int));

  printf("cache gives img %ix%i has alpha: %i expecting %i bytes\n", img_w, img_h, has_alpha, img_w * img_h * ( 3 + has_alpha));

  img_data = malloc(sizeof(unsigned char) * img_w * img_h * ( 3 + has_alpha));

  tmp_ptr = img_data;

  printf("gzread gives %i\n", gzread (cache_file, (void *)img_data, img_w * img_h * ( 3 + has_alpha)));

  item->icon = mb_pixbuf_img_new_from_data(mb->pixbuf, 
                                 tmp_ptr, img_w, img_h,
                                 has_alpha);
  free(tmp_ptr);
  gzclose (cache_file);
  free(md5);

  return item;
}



/* Should these live here ?? */

void
mbdesktop_item_folder_activate_cb(void *data1, void *data2)
{
  MBDesktop *mb = (MBDesktop *)data1; 
  MBDesktopItem *item = (MBDesktopItem *)data2; 

  /* Save scroll position if relevant */
  if (mb->scroll_offset_item)
    item->saved_scroll_offset_item = mb->scroll_offset_item; 

  mb->scroll_offset_item = mb->kbd_focus_item 
    = mb->current_head_item = item->item_child;

  mb->current_folder_item = item; 

  if (mb->kbd_focus_item->item_next_sibling)
    mb->kbd_focus_item = mb->kbd_focus_item->item_next_sibling;

  mbdesktop_view_paint(mb, False);
}

void
mbdesktop_item_folder_prev_activate_cb(void *data1, void *data2)
{
  MBDesktop *mb = (MBDesktop *)data1; 
  MBDesktopItem *item = (MBDesktopItem *)data2; 

  if (item && item->type == ITEM_TYPE_PREVIOUS && item->item_parent)
    {
      mb->kbd_focus_item = item->item_parent;

      mb->scroll_offset_item  = mb->current_head_item 
      = mbdesktop_item_get_first_sibling(item->item_parent);

      /* Get saved scroll position if exists */
      if (item->item_parent->saved_scroll_offset_item)
      mb->scroll_offset_item = item->item_parent->saved_scroll_offset_item;

      item->item_parent->saved_scroll_offset_item = NULL;
      
      mb->current_folder_item = item->item_parent->item_parent; 
      
      mbdesktop_view_paint(mb, False);
    }
}

MBDesktopItem *
mbdesktop_item_get_from_coords(MBDesktop *mb, int x, int y)
{
  MBDesktopItem *item;
  for(item = mb->scroll_offset_item; 
      (item != NULL && item != mb->last_visible_item); 
      item = item->item_next_sibling)
    {
      if (x > item->x && x < (item->x + item->width)
        && y > item->y && y < (item->y + item->height))
      {
        return item;
      } 
    }
  return NULL;
}




Generated by  Doxygen 1.6.0   Back to index