Add watch_columns config option. (Darshan Shaligram <scintilla@gmail.com>)

git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@591 db0b04b0-f4d1-0310-9a6d-de3e77497b0e
This commit is contained in:
Pasi Kallinen 2011-10-03 14:46:42 +00:00
parent 9fc78de52e
commit a224b6582c
4 changed files with 170 additions and 44 deletions

View File

@ -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; }

View File

@ -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,11 +273,47 @@ 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
{
if (curr_menu->banner_fn) {
@ -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();
}

View 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 */

View 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;
};