From a224b6582c3eea9837c3fe50d2e08318186fe2c8 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 3 Oct 2011 14:46:42 +0000 Subject: [PATCH] Add watch_columns config option. (Darshan Shaligram ) git-svn-id: svn://katsu.triplehelix.org/dgamelaunch/trunk@591 db0b04b0-f4d1-0310-9a6d-de3e77497b0e --- config.l | 1 + config.y | 77 ++++++++++++++++++++++++++------ dgamelaunch.c | 121 +++++++++++++++++++++++++++++++++++++------------- dgamelaunch.h | 15 +++++++ 4 files changed, 170 insertions(+), 44 deletions(-) diff --git a/config.l b/config.l index a7d05b4..afcc8a6 100644 --- 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; } diff --git a/config.y b/config.y index f2c2588..0350840 100644 --- 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,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(); } diff --git a/dgamelaunch.c b/dgamelaunch.c index 28e8a06..fa9768c 100644 --- a/dgamelaunch.c +++ b/dgamelaunch.c @@ -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 */ diff --git a/dgamelaunch.h b/dgamelaunch.h index 4be7815..fdfe579 100644 --- a/dgamelaunch.h +++ b/dgamelaunch.h @@ -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; };