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 {
%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
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;
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
{
| 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; }
;
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();
}
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)
{
}
#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)
{
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;
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);
}
}
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;
}
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;
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 */