]> skyeroc.xyz Git - dgamelaunch/commitdiff
Add watch_columns config option. (Darshan Shaligram <scintilla@gmail.com>)
authorPasi Kallinen <paxed@alt.org>
Mon, 3 Oct 2011 14:46:42 +0000 (14:46 +0000)
committerPasi Kallinen <paxed@alt.org>
Mon, 3 Oct 2011 14:46:42 +0000 (14:46 +0000)
git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@591 db0b04b0-f4d1-0310-9a6d-de3e77497b0e

config.l
config.y
dgamelaunch.c
dgamelaunch.h

index a7d05b4f291def0df64fee74308e4d10241de8e7..afcc8a6691d5d718531b71bb4cd90faea54b68ea 100644 (file)
--- a/config.l
+++ b/config.l
@@ -88,6 +88,7 @@ cursor                { return TYPE_CURSOR; }
 "ttyrecdir"    { return TYPE_PATH_TTYREC; }
 server_id      { return TYPE_SERVER_ID; }
 sortmode       { return TYPE_WATCH_SORTMODE; }
+watch_columns  { return TYPE_WATCH_COLUMNS; }
 commands       { return TYPE_CMDQUEUE; }
 postcommands   { return TYPE_POSTCMDQUEUE; }
 yes            { yylval.i = 1; return TYPE_BOOL; }
index f2c258833c177ec156c26641cb87b12e83f6c773..0350840cc3acdfa554f5c3868e55687f2f8aaaa4 100644 (file)
--- a/config.y
+++ b/config.y
@@ -21,10 +21,25 @@ extern int num_games;
 int ncnf = 0;
 struct dg_cmdpart *curr_cmdqueue = NULL;
 struct dg_menu *curr_menu = NULL;
+
+static struct dg_watchcols *curr_watch_columns[DGL_MAXWATCHCOLS];
+static int curr_n_watch_columns = 0;
+
 int cmdqueue_num = -1;
 
 static const char* lookup_token (int t);
 
+static int sortmode_number(const char *sortmode_name) {
+    int tmpi;
+    if (!*sortmode_name)
+        return SORTMODE_NONE;
+    for (tmpi = SORTMODE_NONE; tmpi < NUM_SORTMODES; tmpi++)
+        if (!strcasecmp(SORTMODE_NAME[tmpi], sortmode_name ))
+            return tmpi;
+    return -1;
+}
+
+
 %}
 
 %union {
@@ -35,7 +50,7 @@ static const char* lookup_token (int t);
 
 %token TYPE_SUSER TYPE_SGROUP TYPE_SGID TYPE_SUID TYPE_MAX TYPE_MAXNICKLEN
 %token TYPE_GAME_SHORT_NAME TYPE_WATCH_SORTMODE TYPE_SERVER_ID
-%token TYPE_ALLOW_REGISTRATION
+%token TYPE_ALLOW_REGISTRATION TYPE_WATCH_COLUMNS
 %token TYPE_PATH_GAME TYPE_NAME_GAME TYPE_PATH_DGLDIR TYPE_PATH_SPOOL
 %token TYPE_PATH_BANNER TYPE_PATH_CANNED TYPE_PATH_CHROOT
 %token TYPE_PATH_PASSWD TYPE_PATH_LOCKFILE TYPE_PATH_TTYREC
@@ -155,16 +170,12 @@ KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']'
 
   case TYPE_WATCH_SORTMODE:
       {
-         int tmpi, okay = 0;
-
-         for (tmpi = (SORTMODE_NONE+1); tmpi < NUM_SORTMODES; tmpi++)
-             if (!strcasecmp(SORTMODE_NAME[tmpi], $3 )) {
-                 globalconfig.sortmode = tmpi;
-                 okay = 1;
-                 break;
-             }
-         if (!okay)
-             fprintf(stderr, "%s:%d: unknown sortmode '%s'\n", config, line, $3);
+          const int sortmode_num = sortmode_number($3);
+         if (sortmode_num <= SORTMODE_NONE)
+             fprintf(stderr, "%s:%d: unknown sortmode '%s'\n", config,
+                      line, $3);
+          else
+              globalconfig.sortmode = sortmode_num;
       }
       break;
 
@@ -262,10 +273,46 @@ KeyPair: TYPE_CMDQUEUE '[' TYPE_CMDQUEUENAME ']'
         config, line, lookup_token($1)); 
       exit(1);
   }
-};
-
+}
+       | TYPE_WATCH_COLUMNS '=' '[' watch_columns ']' {
+            memcpy(globalconfig.watch_columns,
+                   curr_watch_columns,
+                   curr_n_watch_columns * sizeof(*curr_watch_columns));
+            globalconfig.n_watch_columns = curr_n_watch_columns;
+            memset(curr_watch_columns, 0, sizeof curr_watch_columns);
+            curr_n_watch_columns = 0;
+          };
+
+
+watch_columns: watch_columns ',' watch_column
+               | watch_column;
+
+watch_column: '[' TYPE_VALUE ',' TYPE_VALUE ',' TYPE_NUMBER ',' TYPE_VALUE ']' {
+    if (curr_n_watch_columns >= DGL_MAXWATCHCOLS) {
+        fprintf(stderr, "%s:%d too many watch column defs (max %d)\n",
+                config, line, DGL_MAXWATCHCOLS);
+        exit(1);
+    }
+
+    {
+        struct dg_watchcols watch_column, *new_watch_column = NULL;
+        watch_column.sortmode = sortmode_number($4);
+        if (watch_column.sortmode == -1) {
+            fprintf(stderr, "%s:%d invalid sort mode '%s'.\n",
+                    config, line, $4);
+            exit(1);
+        }
+        watch_column.dat = watch_column.sortmode;
+        watch_column.x = $6;
+        watch_column.colname = strdup($2);
+        watch_column.fmt = strdup($8);
 
+        new_watch_column = (struct dg_watchcols *) malloc(sizeof watch_column);
+        memcpy(new_watch_column, &watch_column, sizeof watch_column);
 
+        curr_watch_columns[curr_n_watch_columns++] = new_watch_column;
+    }
+};
 
 menu_definition : TYPE_BANNER_FILE '=' TYPE_VALUE
          {
@@ -559,6 +606,7 @@ KeyType : TYPE_SUSER        { $$ = TYPE_SUSER; }
        | TYPE_PATH_INPROGRESS  { $$ = TYPE_PATH_INPROGRESS; }
        | TYPE_RC_FMT           { $$ = TYPE_RC_FMT; }
        | TYPE_WATCH_SORTMODE   { $$ = TYPE_WATCH_SORTMODE; }
+       | TYPE_WATCH_COLUMNS    { $$ = TYPE_WATCH_COLUMNS; }
        | TYPE_SERVER_ID        { $$ = TYPE_SERVER_ID; }
        ;
 
@@ -590,6 +638,7 @@ const char* lookup_token (int t)
     case TYPE_MAX_IDLE_TIME: return "max_idle_time";
     case TYPE_RC_FMT: return "rc_fmt";
     case TYPE_WATCH_SORTMODE: return "sortmode";
+    case TYPE_WATCH_COLUMNS: return "watch_columns";
     case TYPE_SERVER_ID: return "server_id";
     default: abort();
   }
index 28e8a0629b67350ce16d02ae93b5a26d0bd01d4b..fa9768c0ffc24cefdf655df5007ac27f6c8bf45f 100644 (file)
@@ -107,6 +107,20 @@ struct dg_user **users = NULL;
 struct dg_user *me = NULL;
 struct dg_banner banner;
 
+static struct dg_watchcols default_watchcols[] = {
+    {0, SORTMODE_NONE,        1, "", "%s)"},
+    {1, SORTMODE_USERNAME,    4, "Username", "%-15s"},
+    {2, SORTMODE_GAMENUM,    21, "Game", "%-5s"},
+    {3, SORTMODE_WINDOWSIZE, 28, " Size", "%s"},
+    {4, SORTMODE_STARTTIME,  37, "Start date & time", "%s"},
+    {5, SORTMODE_IDLETIME,   58, "Idle time", "%-10s"},
+#ifdef USE_SHMEM
+    {6, SORTMODE_WATCHERS,   70, "Watchers", "%s"},
+#endif
+};
+
+static struct dg_watchcols *default_watchcols_list[DGL_MAXWATCHCOLS + 1];
+
 struct dg_user *
 cpy_me(struct dg_user *me)
 {
@@ -680,6 +694,68 @@ shm_dump()
 }
 #endif
 
+static
+struct dg_watchcols **
+globalconfig_watch_columns()
+{
+    if (globalconfig.n_watch_columns)
+        return globalconfig.watch_columns;
+
+    if (!*default_watchcols_list) {
+        int i;
+        for (i = 0; i < ARRAY_SIZE(default_watchcols); ++i)
+            default_watchcols_list[i] = &default_watchcols[i];
+    }
+    return default_watchcols_list;
+}
+
+static
+int
+watchcol_find_index(struct dg_watchcols **watchcols,
+                    int sortmode)
+{
+    int i;
+    for (i = 0; watchcols[i]; ++i)
+        if (watchcols[i]->sortmode == sortmode)
+            return i;
+    return -1;
+}
+
+static
+void
+sortmode_increment(struct dg_watchcols **watchcols,
+                   dg_sortmode *sortmode,
+                   int direction)
+{
+    int watch_column_index = watchcol_find_index(watchcols, *sortmode);
+    int n_watchcols;
+    int wrap_count = 0;
+    const dg_sortmode old_sortmode = *sortmode;
+
+    for (n_watchcols = 0; watchcols[n_watchcols]; ++n_watchcols)
+        ;
+
+    if (watch_column_index == -1 || !n_watchcols)
+        return;
+
+    do {
+        watch_column_index += direction;
+
+        if (watch_column_index < 0) {
+            watch_column_index = n_watchcols - 1;
+            ++wrap_count;
+        } else if (watch_column_index >= n_watchcols) {
+            watch_column_index = 0;
+            ++wrap_count;
+        }
+
+        *sortmode = watchcols[watch_column_index]->sortmode;
+    } while (wrap_count < 2 && !*sortmode);
+
+    if (!*sortmode)
+        *sortmode = old_sortmode;
+}
+
 void
 inprogressmenu (int gameid)
 {
@@ -709,31 +785,14 @@ inprogressmenu (int gameid)
 
   int require_enter = 0; /* TODO: make configurable */
 
-  int di;
-
   time_t ctime;
 
-  struct dg_watchcols {
-      int dat;
-      int sortmode;
-      int x;
-      char *colname;
-      char *fmt;
-  } watchcols[] = {
-      {0, SORTMODE_NONE,        1, "", "%s)"},
-      {1, SORTMODE_USERNAME,    4, "Username", "%-15s"},
-      {2, SORTMODE_GAMENUM,    21, "Game", "%-5s"},
-      {3, SORTMODE_WINDOWSIZE, 28, " Size", "%s"},
-      {4, SORTMODE_STARTTIME,  37, "Start date & time", "%s"},
-      {5, SORTMODE_IDLETIME,   58, "Idle time", "%-10s"},
-#ifdef USE_SHMEM
-      {6, SORTMODE_WATCHERS,   70, "Watchers", "%s"},
-#endif
-  };
-
   struct dg_shm *shm_dg_data = NULL;
   struct dg_shm_game *shm_dg_game = NULL;
 
+  struct dg_watchcols **watchcols = globalconfig_watch_columns();
+  struct dg_watchcols **curr_watchcol;
+
   if (sortmode == NUM_SORTMODES)
       sortmode = globalconfig.sortmode;
 
@@ -766,13 +825,14 @@ inprogressmenu (int gameid)
          if (offset < 0) offset = 0;
          mvaddstr (3, 1, "The following games are in progress:");
 
-         for (di = 0; di < ARRAY_SIZE(watchcols); di++) {
-             char *col = watchcols[di].colname;
-             int x = watchcols[di].x;
+         for (curr_watchcol = watchcols; *curr_watchcol; ++curr_watchcol) {
+              struct dg_watchcols *wcol = *curr_watchcol;
+             char *col = wcol->colname;
+             int x = wcol->x;
              while (*col == ' ') { x++; col++; }
-             if (sortmode == watchcols[di].sortmode) attron(title_attr);
+             if (sortmode == wcol->sortmode) attron(title_attr);
              mvprintw(top_banner_hei, x, col);
-             if (sortmode == watchcols[di].sortmode) attroff(title_attr);
+             if (sortmode == wcol->sortmode) attroff(title_attr);
          }
       }
 
@@ -808,10 +868,11 @@ inprogressmenu (int gameid)
                  snprintf(idletime, 10, " ");
          }
 
-         for (di = 0; di < ARRAY_SIZE(watchcols); di++) {
+         for (curr_watchcol = watchcols; *curr_watchcol; ++curr_watchcol) {
+              struct dg_watchcols *col = *curr_watchcol;
              char tmpbuf[80];
              int hilite = 0;
-             switch (watchcols[di].dat) {
+             switch (col->dat) {
              default: break;
              case 0: tmpbuf[0] = selectorchars[i]; tmpbuf[1] = '\0'; break;
              case 1: snprintf(tmpbuf, 80, "%s", games[i + offset]->name); break;
@@ -829,7 +890,7 @@ inprogressmenu (int gameid)
              }
              tmpbuf[79] = '\0';
              if (hilite) attron(hilite);
-             mvprintw(top_banner_hei + 1 + i, watchcols[di].x, watchcols[di].fmt, tmpbuf);
+             mvprintw(top_banner_hei + 1 + i, col->x, col->fmt, tmpbuf);
              if (hilite) {
                  attron(CLR_NORMAL);
                  hilite = 0;
@@ -938,11 +999,11 @@ inprogressmenu (int gameid)
           return;
        case KEY_RIGHT:
        case '.':
-           if (sortmode < (NUM_SORTMODES-1)) sortmode++; else sortmode = SORTMODE_USERNAME;
+            sortmode_increment(watchcols, &sortmode, 1);
            break;
        case KEY_LEFT:
        case ',':
-           if (sortmode > SORTMODE_USERNAME) sortmode--; else sortmode = (NUM_SORTMODES-1);
+            sortmode_increment(watchcols, &sortmode, -1);
            break;
 
        case 12: case 18: /* ^L, ^R */
index 4be7815d2c5b3e0dbc95783c68cab19aa3470d8b..fdfe57925c9e5bed941ed821b660e44b106156bb 100644 (file)
@@ -23,6 +23,9 @@
 #define DGL_PASSWDLEN 20 /* max. length of passwords */
 #define DGL_MAILMSGLEN 80 /* max. length of mail message */
 
+#define DGL_MAXWATCHCOLS 10
+
+
 #ifdef USE_NCURSES_COLOR
 # define CLR_NORMAL  COLOR_PAIR(1)   | A_NORMAL
 # define CLR_RED     COLOR_PAIR(2)   | A_NORMAL
@@ -191,6 +194,14 @@ struct dg_config
     int max_idle_time;
 };
 
+struct dg_watchcols {
+    int dat;
+    int sortmode;
+    int x;
+    char *colname;
+    char *fmt;
+};
+
 struct dg_globalconfig
 {
     char* chroot;
@@ -210,6 +221,10 @@ struct dg_globalconfig
 
     struct dg_cmdpart *cmdqueue[NUM_DGLTIMES];
 
+    /* NULL terminated list of dg_watchcols pointers */
+    struct dg_watchcols *watch_columns[DGL_MAXWATCHCOLS + 1];
+    int n_watch_columns;
+
     struct dg_menulist *menulist;
     int menu_max_idle_time;
 };