From bbe4a3d33023e4557320a478bf1e800730e900f3 Mon Sep 17 00:00:00 2001 From: Qball Cow Date: Thu, 30 Jan 2014 00:47:23 +0100 Subject: [PATCH] Add dmenu option --- include/dmenu-dialog.h | 7 +++ include/simpleswitcher.h | 1 + source/dmenu-dialog.c | 129 +++++++++++++++++++++++++++++++++++++++ source/simpleswitcher.c | 8 ++- 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 include/dmenu-dialog.h create mode 100644 source/dmenu-dialog.c diff --git a/include/dmenu-dialog.h b/include/dmenu-dialog.h new file mode 100644 index 00000000..ff04a66a --- /dev/null +++ b/include/dmenu-dialog.h @@ -0,0 +1,7 @@ +#ifndef __DMENU_DIALOG_H__ +#define __DMENU_DIALOG_H__ + +extern char *dmenu_prompt; +SwitcherMode dmenu_switcher_dialog ( char **input ); + +#endif diff --git a/include/simpleswitcher.h b/include/simpleswitcher.h index 7d79e989..7775ec0e 100644 --- a/include/simpleswitcher.h +++ b/include/simpleswitcher.h @@ -26,6 +26,7 @@ typedef enum { #endif NUM_DIALOGS, JSON_DIALOG, + DMENU_DIALOG, MODE_EXIT, NEXT_DIALOG } SwitcherMode; diff --git a/source/dmenu-dialog.c b/source/dmenu-dialog.c new file mode 100644 index 00000000..adb0427a --- /dev/null +++ b/source/dmenu-dialog.c @@ -0,0 +1,129 @@ +/** + * simpleswitcher + * + * MIT/X11 License + * Copyright 2013-2014 Qball Cow + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#define _GNU_SOURCE +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "simpleswitcher.h" +#include "mark-dialog.h" +#include +#include +#include +#include +#include + +#ifdef TIMING +#include +#endif + +char *dmenu_prompt = "dmenu "; + +static char **get_dmenu ( ) +{ + +#ifdef TIMING + struct timespec start, stop; + clock_gettime( CLOCK_REALTIME, &start ); +#endif + char **retv = NULL; + int index = 0; + + char buffer[1024]; + while(fgets(buffer, 1024, stdin) != NULL) { + retv = realloc(retv, (index+2)*sizeof(char*)); + retv[index] = strdup(buffer); + retv[index][strlen(buffer)-1] = '\0'; + retv[index+1] = NULL; + index++; + } + + + +#ifdef TIMING + clock_gettime( CLOCK_REALTIME, &stop ); + + if ( stop.tv_sec != start.tv_sec ) { + stop.tv_nsec += ( stop.tv_sec-start.tv_sec )*1e9; + } + + long diff = stop.tv_nsec-start.tv_nsec; + printf( "Time elapsed: %ld us\n", diff/1000 ); +#endif + return retv; +} + +static int token_match ( char **tokens, const char *input, + __attribute__( ( unused ) )int index, + __attribute__( ( unused ) )void *data ) +{ + int match = 1; + + // Do a tokenized match. + if ( tokens ) for ( int j = 1; match && tokens[j]; j++ ) { + match = ( strcasestr( input, tokens[j] ) != NULL ); + } + + return match; +} + +SwitcherMode dmenu_switcher_dialog ( char **input ) +{ + SwitcherMode retv = MODE_EXIT; + // act as a launcher + char **list = get_dmenu( ); + + if ( list == NULL ) { + return retv; + } + + int shift=0; + int n = menu( list, input, dmenu_prompt,NULL, &shift,token_match, NULL ); + + if ( n == -2 ) { + retv = DMENU_DIALOG; + } else if ( n >=0 && list[n] != NULL ) { + fputs(list[n],stdout); + } + + for ( unsigned int i=0; list[i] != NULL; i++ ) { + free( list[i] ); + } + free(list); + + return retv; +} + diff --git a/source/simpleswitcher.c b/source/simpleswitcher.c index 0b9351d1..a33a91e5 100644 --- a/source/simpleswitcher.c +++ b/source/simpleswitcher.c @@ -67,6 +67,7 @@ #include "mark-dialog.h" #include "profile-dialog.h" #include "json-dialog.h" +#include "dmenu-dialog.h" #define LINE_MARGIN 4 @@ -1202,6 +1203,9 @@ void run_switcher( int fmode, SwitcherMode mode ) else if ( mode == JSON_DIALOG ) { retv = json_switcher_dialog ( &input ); } + else if ( mode == DMENU_DIALOG ) { + retv = dmenu_switcher_dialog ( &input ); + } if ( retv == NEXT_DIALOG ) { mode = ( mode+1 )%NUM_DIALOGS; @@ -1430,7 +1434,9 @@ int main( int argc, char *argv[] ) } else if ( find_arg( argc, argv, "-json" ) >= 0 ) { find_arg_str( argc, argv, "-json", &json_input_file); run_switcher( NOFORK, JSON_DIALOG ); - + } else if ( find_arg( argc, argv, "-dmenu" ) >= 0 ) { + find_arg_str( argc, argv, "-dmenu", &dmenu_prompt); + run_switcher( NOFORK, DMENU_DIALOG); } else { // Daemon mode, Listen to key presses..