Changeset 24 for trunk/gtk


Ignore:
Timestamp:
Jan 12, 2006, 7:04:05 PM (16 years ago)
Author:
root
Message:

Update 2006-01-03

Location:
trunk/gtk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/conf.c

    r7 r24  
    450450  for(ii = 0; ii < count; ii++) {
    451451    /* XXX need a better way to query running/stopped state */
    452     paused = (TR_STATUS_STOPPING == torrents[ii].status ||
    453               TR_STATUS_STOPPED == torrents[ii].status ||
    454               TR_STATUS_PAUSE == torrents[ii].status);
     452    paused = ((TR_STATUS_STOPPING | TR_STATUS_PAUSE) & torrents[ii].status);
    455453    torrentfile = g_strescape(torrents[ii].info.torrent, "");
    456454    torrentdir = g_strescape(torrents[ii].folder, "");
  • trunk/gtk/main.c

    r23 r24  
    7777gboolean
    7878exitcheck(gpointer gdata);
     79void
     80stoptransmission(void *tr);
    7981GtkWidget *
    8082makewind_toolbar(struct cbdata *data);
     
    105107void
    106108actionclick(GtkWidget *widget, gpointer gdata);
     109gint
     110intrevcmp(gconstpointer a, gconstpointer b);
    107111void
    108112doubleclick(GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *col,
     
    169173  tr = tr_init();
    170174
     175  setuphandlers(stoptransmission, tr);
     176
    171177  if(cf_init(tr_getPrefsDirectory(), &err)) {
    172178    if(cf_lock(&err)) {
     
    202208        gtk_widget_show_all(stateerr);
    203209    } else {
    204       gtk_widget_show(errmsg_full(NULL, (errfunc_t)gtk_main_quit,
     210      gtk_widget_show(errmsg_full(NULL, (callbackfunc_t)gtk_main_quit,
    205211                                  NULL, "%s", err));
    206212      g_free(err);
    207213    }
    208214  } else {
    209     gtk_widget_show(errmsg_full(NULL, (errfunc_t)gtk_main_quit,
     215    gtk_widget_show(errmsg_full(NULL, (callbackfunc_t)gtk_main_quit,
    210216                                NULL, "%s", err));
    211217    g_free(err);
     
    309315  data->timer = -1;
    310316
     317  blocksigs();
     318
    311319  for(ii = tr_torrentStat(data->tr, &st); 0 < ii; ii--) {
    312320    if(TR_TORRENT_NEEDS_STOP(st[ii-1].status)) {
     
    320328  free(st);
    321329
     330  unblocksigs();
     331
    322332  /* XXX should disable widgets or something */
    323333
     
    340350  int ii;
    341351
     352  blocksigs();
     353
    342354  for(ii = tr_torrentStat(data->cbdata->tr, &st); 0 < ii; ii--) {
    343     if(TR_STATUS_PAUSE == st[ii-1].status) {
     355    if(TR_STATUS_PAUSE & st[ii-1].status) {
    344356      /*fprintf(stderr, "quit: closing %i %s\n", ii, st[ii-1].info.name);*/
    345357      tr_torrentClose(data->cbdata->tr, ii - 1);
     
    354366     time(NULL) - data->started < TRACKER_EXIT_TIMEOUT) {
    355367    updatemodel(data->cbdata);
     368    unblocksigs();
    356369    return TRUE;
    357370  }
    358 
    359   /*fprintf(stderr, "quit: giving up on %i torrents\n",
    360     tr_torrentCount(data->cbdata->tr));*/
    361 
    362   for(ii = tr_torrentCount(data->cbdata->tr); 0 < ii; ii--)
    363     tr_torrentClose(data->cbdata->tr, ii - 1);
    364371
    365372  /* exit otherwise */
     
    369376  data->timer = -1;
    370377
     378  /*fprintf(stderr, "quit: giving up on %i torrents\n",
     379    tr_torrentCount(data->cbdata->tr));*/
     380  stoptransmission(data->cbdata->tr);
     381  clearhandlers();
     382  unblocksigs();
     383
    371384  gtk_widget_destroy(GTK_WIDGET(data->cbdata->wind));
    372   tr_close(data->cbdata->tr);
    373385  g_free(data->cbdata);
    374386  g_free(data);
     
    376388
    377389  return FALSE;
     390}
     391
     392void
     393stoptransmission(void *tr) {
     394  while(0 < tr_torrentCount(tr))
     395    tr_torrentClose(tr, 0);
     396  tr_close(tr);
    378397}
    379398
     
    590609  char *upstr, *downstr, *str;
    591610
     611  blocksigs();
     612
    592613  max = tr_torrentStat(data->tr, &st);
    593614  for(ii = 0; ii < max; ii++) {
     
    626647  /* the status of the selected item may have changed, so update the buttons */
    627648  fixbuttons(NULL, data);
     649
     650  unblocksigs();
    628651
    629652  return TRUE;
     
    791814  assert(actindex < ALEN(actionitems));
    792815
     816  blocksigs();
    793817  updatesave = FALSE;
    794818  count = tr_torrentStat(data->tr, &sb);
    795819
    796   for(ii = g_list_first(ids); NULL != ii; ii = ii->next) {
     820  for(ii = g_list_sort(ids, intrevcmp); NULL != ii; ii = ii->next) {
    797821    index = GPOINTER_TO_INT(ii->data);
    798822    if(index >= count) {
     
    820844        tr_torrentClose(data->tr, index);
    821845        updatesave = TRUE;
     846        /* XXX should only unselect deleted rows */
     847        gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(data->view));
    822848        break;
    823849      case ACT_INFO:
     
    836862  }
    837863
     864  unblocksigs();
     865
    838866  if(FROM_BUTTON == from)
    839867    g_list_free(ids);
     868}
     869
     870gint
     871intrevcmp(gconstpointer a, gconstpointer b) {
     872  int aint = GPOINTER_TO_INT(a);
     873  int bint = GPOINTER_TO_INT(b);
     874
     875  if(bint > aint)
     876    return 1;
     877  else if(bint < aint)
     878    return -1;
     879  else
     880    return 0;
    840881}
    841882
     
    867908  }
    868909
     910  blocksigs();
     911
    869912  if(0 != tr_torrentInit(tr, torrent)) {
     913    unblocksigs();
    870914    /* XXX would be nice to have errno strings, are they printed to stdout? */
    871915    errmsg(parentwind, "Failed to open torrent file %s", torrent);
     
    887931  if(!paused)
    888932    tr_torrentStart(tr, tr_torrentCount(tr) - 1);
     933
     934  unblocksigs();
     935
    889936  return TRUE;
    890937}
     
    909956    ret = cf_savestate(count, stat, &errstr);
    910957  else {
     958    blocksigs();
    911959    count = tr_torrentStat(tr, &st);
     960    unblocksigs();
    912961    ret = cf_savestate(count, st, &errstr);
    913962    free(st);
  • trunk/gtk/util.c

    r11 r24  
    2828#include <sys/stat.h>
    2929#include <errno.h>
     30#include <signal.h>
    3031#include <stdarg.h>
    3132#include <string.h>
     
    3536#include "util.h"
    3637
     38static void
     39sigexithandler(int sig);
    3740static void
    3841errcb(GtkWidget *wind, int resp, gpointer data);
     
    99102}
    100103
     104static int exit_sigs[] = {SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2};
     105static callbackfunc_t exit_func = NULL;
     106static void *exit_data = NULL;
     107static int exit_block_level = 0;
     108
     109void
     110setuphandlers(callbackfunc_t func, void *data) {
     111  struct sigaction sa;
     112  unsigned int ii;
     113
     114  exit_data = data;
     115  exit_func = func;
     116
     117  bzero(&sa, sizeof(sa));
     118  sa.sa_handler = sigexithandler;
     119  for(ii = 0; ii < ALEN(exit_sigs); ii++)
     120    sigaction(exit_sigs[ii], &sa, NULL);
     121}
     122
     123void
     124clearhandlers(void) {
     125  struct sigaction sa;
     126  unsigned int ii;
     127
     128  bzero(&sa, sizeof(sa));
     129  sa.sa_handler = SIG_DFL;
     130  for(ii = 0; ii < ALEN(exit_sigs); ii++)
     131    sigaction(exit_sigs[ii], &sa, NULL);
     132}
     133
     134static void
     135sigexithandler(int sig) {
     136  exit_func(exit_data);
     137  clearhandlers();
     138  raise(sig);
     139}
     140
     141void
     142blocksigs(void) {
     143  sigset_t mask;
     144  unsigned int ii;
     145
     146  if(0 < (exit_block_level++))
     147    return;
     148
     149  sigemptyset(&mask);
     150  for(ii = 0; ii < ALEN(exit_sigs); ii++)
     151    sigaddset(&mask, exit_sigs[ii]);
     152  sigprocmask(SIG_BLOCK, &mask, NULL);
     153}
     154
     155void
     156unblocksigs(void) {
     157  sigset_t mask;
     158  unsigned int ii;
     159
     160  if(0 < (--exit_block_level))
     161    return;
     162
     163  sigemptyset(&mask);
     164  for(ii = 0; ii < ALEN(exit_sigs); ii++)
     165    sigaddset(&mask, exit_sigs[ii]);
     166  sigprocmask(SIG_UNBLOCK, &mask, NULL);
     167}
     168
    101169GtkWidget *
    102170errmsg(GtkWindow *wind, const char *format, ...) {
     
    112180
    113181GtkWidget *
    114 errmsg_full(GtkWindow *wind, errfunc_t func, void *data,
     182errmsg_full(GtkWindow *wind, callbackfunc_t func, void *data,
    115183            const char *format, ...) {
    116184  GtkWidget *dialog;
     
    125193
    126194GtkWidget *
    127 verrmsg(GtkWindow *wind, errfunc_t func, void *data,
     195verrmsg(GtkWindow *wind, callbackfunc_t func, void *data,
    128196        const char *format, va_list ap) {
    129197  GtkWidget *dialog;
     
    156224errcb(GtkWidget *widget, int resp SHUTUP, gpointer data) {
    157225  GList *funcdata;
    158   errfunc_t func;
     226  callbackfunc_t func;
    159227
    160228  if(NULL != data) {
  • trunk/gtk/util.h

    r11 r24  
    4141#define ALEN(a)                 (sizeof(a) / sizeof((a)[0]))
    4242
     43/* used for a callback function with a data parameter */
     44typedef void (*callbackfunc_t)(void*);
     45
     46/* try to interpret a string as a textual representation of a boolean */
    4347gboolean
    4448strbool(const char *str);
    4549
     50/* return a human-readable string for the size given in bytes with the
     51   requested number of decimal places.  the string must be g_free()d */
    4652char *
    4753readablesize(guint64 size, int decimals);
    4854
     55/* create a directory and any missing parent directories */
    4956gboolean
    5057mkdir_p(const char *name, mode_t mode);
    5158
    52 typedef void (*errfunc_t)(void*);
     59/* set up a handler for various fatal signals */
     60void
     61setuphandlers(callbackfunc_t func, void *data);
     62
     63/* clear the handlers for fatal signals */
     64void
     65clearhandlers(void);
     66
     67/* blocks and unblocks delivery of fatal signals. calls to these
     68   functions can be nested as long as unblocksigs() is called exactly
     69   as many times as blocksigs().  only the first blocksigs() will
     70   block signals and only the last unblocksigs() will unblock them. */
     71void
     72blocksigs(void);
     73void
     74unblocksigs(void);
    5375
    5476/* if wind is NULL then you must call gtk_widget_show on the returned widget */
     
    6284
    6385GtkWidget *
    64 errmsg_full(GtkWindow *wind, errfunc_t func, void *data,
     86errmsg_full(GtkWindow *wind, callbackfunc_t func, void *data,
    6587            const char *format, ...)
    6688#ifdef __GNUC__
     
    7092
    7193GtkWidget *
    72 verrmsg(GtkWindow *wind, errfunc_t func, void *data,
     94verrmsg(GtkWindow *wind, callbackfunc_t func, void *data,
    7395        const char *format, va_list ap);
    7496
Note: See TracChangeset for help on using the changeset viewer.