Back to index

indicator-appmenu  12.10.0
hud-cli.c
Go to the documentation of this file.
00001 /*
00002 Small utility to excersise the HUD from the command line
00003 
00004 Copyright 2011 Canonical Ltd.
00005 
00006 Authors:
00007     Ted Gould <ted@canonical.com>
00008 
00009 This program is free software: you can redistribute it and/or modify it 
00010 under the terms of the GNU General Public License version 3, as published 
00011 by the Free Software Foundation.
00012 
00013 This program is distributed in the hope that it will be useful, but 
00014 WITHOUT ANY WARRANTY; without even the implied warranties of 
00015 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
00016 PURPOSE.  See the GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License along 
00019 with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 */
00021 
00022 #include <glib.h>
00023 #include <gio/gunixinputstream.h>
00024 #include <gtk/gtk.h>
00025 #include <unistd.h>
00026 #include <stdio.h>
00027 #include <readline/readline.h>
00028 #include <readline/history.h>
00029 #include <stdlib.h>
00030 #include <curses.h>
00031 
00032 #include "shared-values.h"
00033 #include "hud.interface.h"
00034 
00035 
00036 static void print_suggestions(const char * query);
00037 static GDBusProxy * proxy = NULL;
00038 static GVariant * last_key = NULL;
00039 static void update(char *string);
00040 void sighandler(int);
00041 
00042 WINDOW *twindow = NULL;
00043 int use_curses = 0;
00044 
00045 int
00046 main (int argc, char *argv[])
00047 {
00048 
00049        g_type_init();
00050 
00051        int single_char;
00052        int pos = 0;
00053        
00054        char *line = (char*) malloc(256 * sizeof(char));
00055 
00056        signal(SIGINT, sighandler);
00057 
00058        GDBusConnection * session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
00059        g_return_val_if_fail(session != NULL, 1);
00060 
00061        GDBusNodeInfo * nodeinfo = g_dbus_node_info_new_for_xml(hud_interface, NULL);
00062        g_return_val_if_fail(nodeinfo != NULL, 1);
00063 
00064        GDBusInterfaceInfo * ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, DBUS_IFACE);
00065        g_return_val_if_fail(ifaceinfo != NULL, 1);
00066 
00067        proxy = g_dbus_proxy_new_sync(session,
00068                                      G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
00069                                      ifaceinfo,
00070                                      DBUS_NAME,
00071                                      DBUS_PATH,
00072                                      DBUS_IFACE,
00073                                      NULL, NULL);
00074        g_return_val_if_fail(proxy != NULL, 1);
00075 
00076 
00077        // reading from pipe
00078        if (!isatty (STDIN_FILENO) ) {
00079               size_t a;
00080               int r;
00081               r = getline (&line, &a, stdin);
00082        
00083               if ( r == -1 ){
00084                      perror("Error reading from pipe");
00085                      exit(EXIT_FAILURE);  
00086               }
00087 
00088               // get rid of newline
00089               if( line[r-1] == '\n' )
00090                      line[r-1] = '\0';    
00091        
00092               printf("\nsearch token: %s\n", line);
00093               print_suggestions( line );
00094        }
00095        // read command line parameter - hud-cli "search string"
00096        else if( argc > 1 ){
00097               printf("\nsearch token: %s\n", argv[1]);
00098               print_suggestions( argv[1] );
00099        }
00100        // interactive mode
00101        else{
00102               use_curses = 1;
00103               
00104               twindow = initscr();               
00105               cbreak();
00106               keypad(stdscr, TRUE);       
00107               noecho();
00108               
00109               /* initialize the query screen */
00110               update( "" );
00111 
00112               /* interactive shell interface */
00113               while( 1 ){
00114               
00115                      single_char = getch();             
00116                      /* need to go left in the buffer */
00117                      if ( single_char == KEY_BACKSPACE ){
00118                             /* don't go too far left */
00119                             if( pos > 0 ){
00120                                    pos--;
00121                                    line[pos] = '\0';
00122                                    update( line );
00123                             }
00124                             else
00125                                    ; /* we are at the beginning of the buffer already */
00126                      }
00127                      /* ENTER will trigger the action for the first selected suggestion */
00128                      else if ( single_char == '\n' ){
00129 
00130                             /* FIXME: execute action on RETURN */
00131                             break;
00132                      }
00133                      /* add character to the buffer and terminate string */
00134                      else if ( single_char != KEY_RESIZE ) {
00135                             if ( pos < 256 -1 ){ // -1 for \0
00136                                    line[pos] = single_char;
00137                                    line[pos+1] = '\0';
00138                                    pos++;
00139                                    update( line );
00140                             }
00141                             else {
00142                                    
00143                             }
00144                      }
00145                      else{
00146                             // nothing to do
00147                      }
00148               }
00149               endwin();
00150        }
00151        
00152        free(line);
00153 
00154        g_dbus_node_info_unref(nodeinfo);
00155        g_object_unref(session);
00156 
00157        return 0;
00158 }
00159 
00160 static void 
00161 update( char *string ){
00162        
00163        werase(twindow);
00164        mvwprintw(twindow, 7, 10, "Search: %s", string);
00165 
00166        print_suggestions( string );
00167        
00168        // move cursor back to input line
00169        wmove( twindow, 7, 10 + 8 + strlen(string) );
00170 
00171        refresh();
00172 }
00173 
00174 
00175 static void 
00176 print_suggestions (const char *query)
00177 {
00178        GError * error = NULL;
00179        GVariantBuilder querybuilder;
00180        g_variant_builder_init(&querybuilder, G_VARIANT_TYPE_TUPLE);
00181        g_variant_builder_add_value(&querybuilder, g_variant_new_string(query));
00182        g_variant_builder_add_value(&querybuilder, g_variant_new_int32(5));
00183 
00184        GVariant * suggests = g_dbus_proxy_call_sync(proxy,
00185                                                     "StartQuery",
00186                                                     g_variant_builder_end(&querybuilder),
00187                                                     G_DBUS_CALL_FLAGS_NONE,
00188                                                     -1,
00189                                                     NULL,
00190                                                     &error);
00191 
00192        if (error != NULL) {
00193               g_warning("Unable to get suggestions: %s", error->message);
00194               g_error_free(error);
00195               return ;
00196        }
00197 
00198        GVariant * target = g_variant_get_child_value(suggests, 0);
00199        g_variant_unref(target);
00200 
00201        GVariant * suggestions = g_variant_get_child_value(suggests, 1);
00202        GVariantIter iter;
00203        g_variant_iter_init(&iter, suggestions);
00204        gchar * suggestion = NULL;
00205        gchar * appicon = NULL;
00206        gchar * icon = NULL;
00207        gchar * complete = NULL;
00208        gchar * accel = NULL;
00209        GVariant * key = NULL;
00210 
00211        last_key = NULL;
00212 
00213        int i=0;
00214        char *clean_line;
00215 
00216        while (g_variant_iter_loop(&iter, "(sssssv)", &suggestion, &appicon, &icon, &complete, &accel, &key)) {
00217               if( use_curses)
00218                      mvwprintw(twindow, 9 + i, 15, "%s", suggestion);
00219               else{
00220                      pango_parse_markup(suggestion, -1, 0, NULL, &clean_line, NULL, NULL);
00221                      printf("\t%s\n", clean_line);
00222                      free(clean_line);
00223               }
00224               i++;
00225 
00226        }
00227 
00228        g_variant_unref(suggestions);
00229 
00230        /* NOTE: Ignoring the Query Key as we're not handling the signal now
00231           and just letting it timeout. */
00232 
00233        return;
00234 }
00235 
00236 void sighandler(int signal){
00237        endwin();
00238        g_object_unref(proxy);
00239        exit(EXIT_SUCCESS);
00240 }