diff -r a79e4a9cb167 dmenu.1 --- a/dmenu.1 Sat Nov 20 09:25:08 2010 +0000 +++ b/dmenu.1 Wed Nov 24 20:59:28 2010 +0200 @@ -11,6 +11,10 @@ .IR monitor ] .RB [ \-p .IR prompt ] +.RB [ \-of +.IR message-file ] +.RB [ \-ol +.IR message-lines ] .RB [ \-fn .IR font ] .RB [ \-nb @@ -59,6 +63,12 @@ .BI \-p " prompt" defines the prompt to be displayed to the left of the input field. .TP +.BI \-of " message-file" +defines the file from which a message is going to be displayed before the prompt. +.TP +.BI \-ol " message-lines" +defines the maximum number of lines of message to display before the prompt. +.TP .BI \-fn " font" defines the font or font set used. .TP diff -r a79e4a9cb167 dmenu.c --- a/dmenu.c Sat Nov 20 09:25:08 2010 +0000 +++ b/dmenu.c Wed Nov 24 20:59:28 2010 +0200 @@ -34,6 +34,8 @@ static size_t nextrune(int incr); static void paste(void); static void readstdin(void); +static void readmsgfile(void); +static void readfile(Item **items, int maxitems, FILE *stream); static void run(void); static void setup(void); static void usage(void); @@ -51,12 +53,15 @@ static const char *normfgcolor = "#000000"; static const char *selbgcolor = "#0066ff"; static const char *selfgcolor = "#ffffff"; +static const char *msgfile = NULL; +static int msglines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; static Bool topbar = True; static DC *dc; static Item *items = NULL; +static Item *msgitems = NULL; static Item *matches, *sel; static Item *prev, *curr, *next; static Window root, win; @@ -97,12 +102,21 @@ selbgcolor = argv[++i]; else if(!strcmp(argv[i], "-sf")) selfgcolor = argv[++i]; + else if(!strcmp(argv[i], "-ol")) + msglines = atoi(argv[++i]); + else if(!strcmp(argv[i], "-of")) + msgfile = argv[++i]; else usage(); + if((!msgfile && msglines!=0) || (lines < 0) || (monitor < -1) || (msglines < 0)) + usage(); + dc = initdc(); initfont(dc, font); readstdin(); + if(msgfile) + readmsgfile(); setup(); run(); @@ -147,6 +161,13 @@ dc->h = bh; drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); + if(msglines) { + dc->w = mw; + for(item = msgitems, curpos = 0; item && curpos < msglines; item = item->next, curpos++) { + drawtext(dc, item->text, selcol); + dc->y += dc->h; + } + } if(prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); @@ -432,10 +453,34 @@ void readstdin(void) { + Item *item; + readfile(&items, 0, stdin); + for(item = items; item; item = item->next) + inputw = MAX(inputw, textw(dc, item->text)); +} + +void +readmsgfile(void) { + Item *item; + FILE *stream; + stream = fopen (msgfile, "r"); + if (!stream) + eprintf("cannot open message file %s\n", msgfile); + readfile(&msgitems, msglines, stream); + fclose(stream); + + msglines = 0; + for(item = msgitems; item; item = item->next) + msglines++; +} + +void +readfile(Item **items, int maxlines, FILE *stream) { char buf[sizeof text], *p; Item *item, **end; + int count; - for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { + for(end = items, count = 0; (!maxlines || count < maxlines) && fgets(buf, sizeof buf, stream); *end = item, end = &item->next, count++) { if((p = strchr(buf, '\n'))) *p = '\0'; if(!(item = malloc(sizeof *item))) @@ -443,7 +488,6 @@ if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); item->next = item->left = item->right = NULL; - inputw = MAX(inputw, textw(dc, item->text)); } } @@ -492,7 +536,7 @@ /* menu geometry */ bh = dc->font.height + 2; lines = MAX(lines, 0); - mh = (lines + 1) * bh; + mh = (msglines + lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { int i, di; @@ -536,7 +580,8 @@ void usage(void) { - fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" + fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt]\n" + " [-of message-file] [-ol message-lines] [-fn font]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); }