added _image_selection_changed(); inside irreco_theme_creator_backgrounds_remove_sele...
[irreco.git] / backend / telnet / src / backend_telnet.c
bloba4aa6b760dcf28900cd9d9a340d72aedfc4b9ee6
1 /*
2 * Irreco Telnet backend
3 * Copyright (C) 2008 Sampo Savola (samposav@paju.oulu.fi)
4 * This backend has some parts from Jami Pekkanen's original mythtv backend
5 * (jami.pekkanen at tkk.fi)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #define IRRECO_DEBUG_PREFIX "TELNET"
23 #include <irreco_util.h>
24 #include <irreco_backend_api.h>
25 #include <unistd.h>
26 #include <malloc.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <netdb.h>
33 #include <arpa/inet.h>
34 #include <gtk/gtk.h>
35 #include <glib.h>
36 #include "config.h"
37 #include <fcntl.h>
38 #include <hildon/hildon-number-editor.h>
40 /* This is used elsewhere too */
41 #define _(String) (String)
43 typedef struct
45 GString *host;
46 gint port;
47 GIOChannel *con;
48 IrrecoKeyFile *keyfile;
49 gchar** keys;
50 gsize length_keys;
51 gsize length_groups;
52 gchar** groups;
53 gint type;
54 char* device;
55 GtkTreeModel *model;
56 GtkTreeIter iter;
57 GtkListStore *store;
58 GtkCellRenderer *renderer;
59 GtkTreeViewColumn *column;
60 GtkWidget *treeview;
62 } TelnetBackend;
64 typedef enum
66 TELNET_BACKEND_ERROR_CONFIG_READ = 1,
67 TELNET_BACKEND_ERROR_CONFIG_WRITE,
68 TELNET_BACKEND_ERROR_CONNECT,
69 TELNET_BACKEND_ERROR_CON_WRITE,
70 TELNET_BACKEND_ERROR_COMMANDS_READ,
71 EDIT_COMMANDS = 0,
72 REMOVE_COMMAND,
73 ADD_COMMAND,
74 ADD_NEW = 0
75 } TelnetBackendError;
76 enum
78 COL_NAME,
79 COL_CMD,
80 NUM_COLS = 2
82 } ;
84 void telnet_backend_edit_commands(TelnetBackend *self, GtkWindow *parent);
85 void telnet_command_edited_callback(GtkCellRendererText *renderer, gchar
86 *path_string,gchar *new_text,
87 TelnetBackend *self);
88 void telnet_backend_add_device(TelnetBackend *self);
89 void remove_command(TelnetBackend *self);
90 void add_command(TelnetBackend *self);
91 void telnet_backend_store_commands(TelnetBackend *self);
92 const char *telnet_backend_get_error_msg(TelnetBackend *self,
93 IrrecoBackendStatus code)
95 switch(code)
97 case TELNET_BACKEND_ERROR_CONFIG_READ:
98 return _("Couldn't read configuration");
99 case TELNET_BACKEND_ERROR_CONFIG_WRITE:
100 return _("Couldn't write configuration");
101 case TELNET_BACKEND_ERROR_CONNECT:
102 return _("Couldn't connect to remote system");
103 case TELNET_BACKEND_ERROR_CON_WRITE:
104 return _("Error while sending data to remote system");
105 case TELNET_BACKEND_ERROR_COMMANDS_READ:
106 return _("Error while reading commands file");
107 default: break;
110 return _("Unknown error");
113 void *telnet_backend_create()
115 TelnetBackend *self;
117 self = g_slice_new0(TelnetBackend);
118 self->host = g_string_new("localhost");
119 self->port = 3333;
120 self->type = 0;
121 self->con = NULL;
122 self->groups = NULL;
123 self->device = NULL;
124 self->keyfile = irreco_keyfile_create
125 ("", TELNET_DATA_DIR"/telnet.conf",
126 NULL);
127 self->groups = g_key_file_get_groups(self->keyfile->keyfile,
128 &self->length_groups);
130 /**create list store **/
132 self->store = gtk_list_store_new (NUM_COLS,
133 G_TYPE_STRING,G_TYPE_STRING);
136 /** tree **/
137 self->model= GTK_TREE_MODEL (self->store);
141 return self;
144 void telnet_backend_disconnect(TelnetBackend *self)
146 if(self->con)
148 g_io_channel_shutdown(self->con, TRUE, NULL);
149 g_io_channel_unref(self->con);
150 self->con = NULL;
154 void telnet_backend_destroy(TelnetBackend *self)
156 telnet_backend_disconnect(self);
157 g_string_free(self->host, TRUE);
158 g_slice_free(TelnetBackend, self);
161 #define TELNET_BACKEND_CONFIG_GROUP "telnet"
163 IrrecoBackendStatus
164 telnet_backend_read_from_conf(TelnetBackend *self,
165 const char *config_file)
168 GKeyFile *avain = NULL;
169 gint port;
170 gint retval;
171 gchar *host = NULL;
172 gchar *device = NULL;
174 IrrecoKeyFile *keyfile = NULL;
176 gchar **commands;
177 gsize commands_length;
179 gint j;
180 GtkTreeIter iter;
183 keyfile = irreco_keyfile_create(
184 g_path_get_dirname(config_file),
185 config_file,
186 TELNET_BACKEND_CONFIG_GROUP);
188 retval = TELNET_BACKEND_ERROR_CONFIG_READ;
190 if(keyfile == NULL) goto cleanup;
191 if(!irreco_keyfile_get_int(keyfile, "port", &port)) goto cleanup;
192 if(!irreco_keyfile_get_str(keyfile, "host", &host)) goto cleanup;
193 if(!irreco_keyfile_get_str(keyfile, "type", &device)) goto cleanup;
197 if(irreco_keyfile_get_gkeyfile(keyfile, &avain)){}
200 commands = g_key_file_get_keys(avain,
201 "commands",&commands_length,NULL);
205 /** read commands from instance conf to model **/
206 if(commands != NULL){
207 for(j=0;j<commands_length;j++){
210 gtk_list_store_append (GTK_LIST_STORE(self->store), &iter);
212 gtk_list_store_set (GTK_LIST_STORE(self->store), &iter,
213 COL_NAME, commands[j],COL_CMD,
214 g_key_file_get_string(avain,"commands",
215 commands[j],NULL),-1);
219 self->port = port;
220 g_string_set_size(self->host, 0);
221 g_string_append(self->host, host);
222 self->device = device;
223 retval = IRRECO_BACKEND_OK;
226 cleanup:
227 irreco_keyfile_destroy(keyfile);
228 g_free(host);
230 return retval;
233 IrrecoBackendStatus
234 telnet_backend_save_to_conf(TelnetBackend *self,
235 const char *config_file)
238 gboolean valid;
239 GKeyFile *keyfile = NULL;
240 gchar *grp = TELNET_BACKEND_CONFIG_GROUP;
242 keyfile = g_key_file_new();
243 g_key_file_set_string(keyfile, grp, "host", self->host->str);
244 g_key_file_set_integer(keyfile, grp, "port", self->port);
245 g_key_file_set_string(keyfile, grp, "type", self->device);
246 valid = gtk_tree_model_get_iter_first (self->model, &self->iter);
248 while (valid)
250 gchar *name;
251 gchar *cmd;
252 gtk_tree_model_get (self->model, &self->iter, COL_NAME, &name,
253 COL_CMD, &cmd, -1);
254 g_key_file_set_string(keyfile, "commands",name,cmd);
255 valid = gtk_tree_model_iter_next (self->model, &self->iter);
261 if(!irreco_write_keyfile(keyfile, config_file))
262 return TELNET_BACKEND_ERROR_CONFIG_WRITE;
264 return IRRECO_BACKEND_OK;
267 IrrecoBackendStatus
268 telnet_backend_get_devices(TelnetBackend *self,
269 IrrecoGetDeviceCallback callback)
272 if(self->groups != NULL)
274 callback(self->device, NULL);
277 return IRRECO_BACKEND_OK;
280 IrrecoBackendStatus
281 telnet_backend_get_commands(TelnetBackend *self,
282 const char *device_name,
283 gpointer device_context,
284 IrrecoGetCommandCallback callback)
286 gboolean valid;
287 valid = gtk_tree_model_get_iter_first (self->model, &self->iter);
289 while (valid)
292 gchar *name;
293 gchar *cmd;
295 gtk_tree_model_get (self->model, &self->iter, COL_NAME, &name,
296 COL_CMD, &cmd, -1);
298 callback(name,cmd);
299 valid = gtk_tree_model_iter_next (self->model, &self->iter);
302 return IRRECO_BACKEND_OK;
305 void
306 telnet_backend_connection_error(TelnetBackend *self, GError *error)
308 /* TODO: See if connection has died? */
309 IRRECO_PRINTF("Connection error occured, Killing connection");
310 telnet_backend_disconnect(self);
313 void telnet_backend_connection_error_callback(GIOChannel *source,
314 GIOCondition cond, TelnetBackend *self)
316 IRRECO_PRINTF("Connection error by callback");
317 /* TODO: Can GError be digged from the object? */
318 telnet_backend_connection_error(self, NULL);
322 IrrecoBackendStatus
323 telnet_backend_connect(TelnetBackend *self)
325 int sock;
326 long arg;
327 int res;
328 int valopt;
329 fd_set myset;
330 socklen_t lon;
331 struct sockaddr_in addr;
332 struct hostent *host;
333 struct timeval tv;
334 IRRECO_PRINTF("Connecting to %s:%d \n", self->host->str, self->port);
336 memset(&addr, '\0', sizeof(addr));
338 sock = socket(AF_INET, SOCK_STREAM, 0);
339 arg = fcntl(sock, F_GETFL, NULL);
340 arg |= O_NONBLOCK;
341 fcntl(sock, F_SETFL, arg);
343 addr.sin_family = AF_INET;
344 addr.sin_port = htons(self->port);
346 if(inet_aton(self->host->str, &addr.sin_addr))
348 IRRECO_PRINTF("Address is IP\n");
350 else if((host = gethostbyname(self->host->str)))
352 IRRECO_PRINTF("Address is valid hostname");
353 memcpy((void *) &addr.sin_addr, (void *) host->h_addr_list[0],
354 (size_t) host->h_length);
356 res = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
358 if (res < 0) {
359 if (errno == EINPROGRESS) {
360 tv.tv_sec = 3;
361 tv.tv_usec = 0;
362 FD_ZERO(&myset);
363 FD_SET(sock, &myset);
364 if (select(sock+1, NULL, &myset, NULL, &tv) > 0)
366 lon = sizeof(int);
367 getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)
368 (&valopt), &lon);
369 if(valopt)
371 IRRECO_PRINTF("Error in connection: %s\n"
372 ,strerror(errno));
373 return TELNET_BACKEND_ERROR_CONNECT;
376 else {
378 IRRECO_PRINTF("Connection timed out: %s\n",
379 strerror(errno));
380 return TELNET_BACKEND_ERROR_CONNECT;
384 else {
386 IRRECO_PRINTF("Couldn't resolve address: %s",
387 strerror(errno));
388 return TELNET_BACKEND_ERROR_CONNECT;
393 arg = fcntl(sock, F_GETFL, NULL);
394 arg &= (~O_NONBLOCK);
395 fcntl(sock, F_SETFL, arg);
397 self->con = g_io_channel_unix_new(sock);
399 g_io_add_watch(self->con, G_IO_ERR,
400 (GIOFunc) telnet_backend_connection_error_callback,
401 self);
403 /* TODO: Should wait until the server responds */
405 return 0; /* IRRECO_BACKEND_OK */
409 IrrecoBackendStatus
410 telnet_backend_ensure_connection(TelnetBackend *self)
412 if(self->con)
414 /* TODO: Better checking? */
415 return 0; /* IRRECO_BACKEND_OK */
417 else
419 return telnet_backend_connect(self);
423 IrrecoBackendStatus
424 telnet_backend_send_command(TelnetBackend *self,
425 const char *device_name,
426 void *device_context,
427 const char *command_name,
428 void *command_context)
430 gsize total_written;
431 gsize written = 0;
432 GString *command;
433 GIOStatus status;
434 GError *error = NULL;
435 int constatus;
437 command = g_string_new((gchar *)command_context);
438 g_string_append(command, "\r\n");
440 IRRECO_PRINTF("In telnet_backend_send_command\n");
442 if((constatus = telnet_backend_ensure_connection(self)))
444 return constatus;
447 IRRECO_PRINTF("Connection ensured, starting write\n");
449 /* TODO: Should read incoming stuff */
451 for(total_written = 0; total_written < command->len;
452 total_written += written)
454 /* TODO: Better error reporting */
455 status = g_io_channel_write_chars(self->con,
456 &(command->str[total_written]), -1, &written, &error);
457 if(status == G_IO_STATUS_ERROR)
459 IRRECO_PRINTF("Failed writing to socket: %s \n",
460 error->message);
461 telnet_backend_connection_error(self, error);
462 return TELNET_BACKEND_ERROR_CON_WRITE;
466 IRRECO_PRINTF("Command written. Flushing\n");
468 status = g_io_channel_flush(self->con, NULL);
470 /* TODO: Better handling for G_IO_STATUS_AGAIN ? */
471 switch(status)
473 case G_IO_STATUS_ERROR:
474 case G_IO_STATUS_AGAIN:
475 telnet_backend_connection_error(self, error);
476 return TELNET_BACKEND_ERROR_CON_WRITE;
477 default: break;
480 IRRECO_PRINTF("Command sent successfully\n");
482 g_string_free(command, TRUE);
484 return IRRECO_BACKEND_OK;
487 IrrecoBackendStatus
488 telnet_backend_configure(TelnetBackend *self,
489 GtkWindow *parent)
491 GtkDialog *dialog;
492 GtkTable *table;
493 GtkEntry *host_widget;
494 GtkWidget* port_editor;
495 const gchar *new_host;
496 gint new_port;
497 GtkComboBox *device;
498 gint response;
499 gboolean loop;
500 int i;
501 gint min_port;
502 gint max_port;
504 min_port = 1;
505 max_port = 65535;
506 device = GTK_COMBO_BOX(gtk_combo_box_new_text());
508 /** get devices to be controlled from telnet.conf **/
509 if(self->groups != NULL ){
510 for(i=0;i<self->length_groups;i++)
512 gtk_combo_box_append_text(GTK_COMBO_BOX(device),self->groups[i]);
514 if(self->device != NULL)
516 if(g_utf8_collate(self->groups[i],self->device) == 0)
518 gtk_combo_box_set_active(GTK_COMBO_BOX(device), i);
521 else
523 gtk_combo_box_set_active(GTK_COMBO_BOX(device), 0);
530 /** **/
531 dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(
532 "Telnet configuration",
533 parent,
534 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
535 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
536 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL));
538 table = GTK_TABLE(gtk_table_new(3, 2, FALSE));
540 host_widget = GTK_ENTRY(gtk_entry_new());
541 gtk_entry_set_text(host_widget, self->host->str);
543 port_editor = hildon_number_editor_new(min_port, max_port);
546 hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(port_editor), self->port);
548 gtk_table_attach_defaults(table,
549 gtk_label_new(_("Host")), 0, 1, 0, 1);
550 gtk_table_attach_defaults(table,
551 GTK_WIDGET(host_widget), 1, 2, 0, 1);
552 gtk_table_attach_defaults(table,
553 gtk_label_new(_("Port")), 0, 1, 1, 2);
554 gtk_table_attach_defaults(table,
555 GTK_WIDGET(port_editor), 1, 2, 1, 2);
556 gtk_table_attach_defaults(table,
557 gtk_label_new(_("Type")), 0, 1, 2, 3);
558 gtk_table_attach_defaults(table,
559 GTK_WIDGET(device), 1, 2, 2, 3);
561 gtk_container_add(GTK_CONTAINER(dialog->vbox), GTK_WIDGET(table));
563 gtk_widget_show_all(GTK_WIDGET(dialog));
567 response = gtk_dialog_run(GTK_DIALOG(dialog));
568 switch(response) {
570 case GTK_RESPONSE_REJECT:
572 loop = FALSE;
573 break;
575 case GTK_RESPONSE_ACCEPT:
577 new_host = gtk_entry_get_text(host_widget);
578 new_port =
579 hildon_number_editor_get_value(
580 HILDON_NUMBER_EDITOR(port_editor));
582 if(gtk_combo_box_get_active_text(
583 GTK_COMBO_BOX(device))!= NULL)
585 self->device =
586 gtk_combo_box_get_active_text(
587 GTK_COMBO_BOX(device));
588 self->port = new_port;
589 g_string_assign(self->host, new_host);
590 telnet_backend_store_commands(self);
593 telnet_backend_disconnect(self);
594 telnet_backend_connect(self);
597 loop = FALSE;
598 break;
601 } while (loop);
602 gtk_widget_destroy(GTK_WIDGET(dialog));
604 return IRRECO_BACKEND_OK;
606 gboolean telnet_backend_is_device_editable(TelnetBackend *self,
607 const gchar * device_name,
608 gpointer device_contex)
611 return TRUE;
613 IrrecoBackendStatus telnet_backend_edit_device(TelnetBackend *self,
614 const char *device_name,
615 gpointer device_contex,
616 GtkWindow *parent)
618 telnet_backend_edit_commands(self, parent);
619 return IRRECO_BACKEND_OK;
622 void telnet_backend_store_commands(TelnetBackend *self){
623 gint j;
624 GtkTreeIter iter;
626 /*gboolean valid;*/
629 /** get keys **/
631 self->keys = g_key_file_get_keys(self->keyfile->keyfile,
632 self->device,&self->length_keys,NULL);
634 /** first clear old entries **/
635 gtk_list_store_clear(GTK_LIST_STORE(self->store));
638 /** add data to the list store **/
639 for(j=0;j<self->length_keys;j++){
641 gtk_list_store_append (GTK_LIST_STORE(self->store), &iter);
642 gtk_list_store_set (GTK_LIST_STORE(self->store), &iter,
643 COL_NAME, self->keys[j],COL_CMD,
644 g_key_file_get_string(
645 self->keyfile->keyfile,
646 self->device,self->keys[j],NULL),-1);
647 /*g_print(self->keys[j]);
649 g_print(g_key_file_get_string(self->keyfile->keyfile,
650 self->device,self->keys[j],NULL));*/
654 /**testitulostus**/
656 valid = gtk_tree_model_get_iter_first (self->model, &self->iter);
658 while (valid)
661 gchar *name;
662 gchar *cmd;
664 gtk_tree_model_get (self->model, &self->iter, COL_NAME, &name,
665 COL_CMD, &cmd, -1);
667 g_print("temp\n");
669 g_print("%s %s \n", name,cmd);
670 valid = gtk_tree_model_iter_next (self->model, &self->iter);
675 void telnet_backend_edit_commands(TelnetBackend *self, GtkWindow *parent)
677 GtkDialog *dialog;
678 /*GtkTable *table;*/
680 GtkWidget *scrollbar;
681 gboolean loop;
682 gint response;
683 GtkWidget *hbox;
684 loop = TRUE;
687 /** treeview **/
688 self->treeview = gtk_tree_view_new_with_model(self->model);
690 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (self->treeview), TRUE);
694 self->model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeview));
695 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(self->treeview),TRUE);
697 /** column for Name **/
698 self->renderer = gtk_cell_renderer_text_new ();
699 g_object_set (self->renderer,
700 "editable", TRUE, NULL);
702 g_signal_connect (self->renderer, "edited",
703 G_CALLBACK (telnet_command_edited_callback), self);
705 g_object_set_data (G_OBJECT (self->renderer), "column",
706 GINT_TO_POINTER (COL_NAME));
708 self->column = gtk_tree_view_column_new_with_attributes ("Name ",
709 self->renderer, "text",COL_NAME,NULL);
711 gtk_tree_view_append_column(GTK_TREE_VIEW(self->treeview), self->column);
712 /** column for Command **/
713 self->renderer = gtk_cell_renderer_text_new ();
714 self->column = gtk_tree_view_column_new_with_attributes ("Command \
716 self->renderer,"text",COL_CMD,NULL);
718 g_object_set (self->renderer, "editable", TRUE, NULL);
720 g_signal_connect (self->renderer, "edited",
721 G_CALLBACK (telnet_command_edited_callback), self);
722 g_object_set_data (G_OBJECT (self->renderer), "column",
723 GINT_TO_POINTER(COL_CMD));
725 gtk_tree_view_append_column(GTK_TREE_VIEW(self->treeview), self->column);
727 /** Create dialog **/
729 dialog = GTK_DIALOG(gtk_dialog_new_with_buttons("Edit Commands",parent,
730 GTK_DIALOG_MODAL, GTK_STOCK_ADD,
731 ADD_COMMAND,GTK_STOCK_REMOVE,
732 REMOVE_COMMAND ,GTK_STOCK_CANCEL,
733 GTK_RESPONSE_REJECT,
734 GTK_STOCK_OK,
735 GTK_RESPONSE_ACCEPT,
736 NULL));
738 /**scrollbar**/
740 scrollbar = gtk_vscrollbar_new(gtk_tree_view_get_vadjustment(
741 GTK_TREE_VIEW(self->treeview)));
743 /**packing**/
745 hbox = gtk_hbox_new (FALSE, 8);
746 gtk_container_add (GTK_CONTAINER (dialog->vbox), hbox);
748 gtk_box_pack_start (GTK_BOX (hbox), self->treeview, FALSE, FALSE, 0);
749 gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
751 gtk_widget_show_all(GTK_WIDGET(dialog));
757 response = gtk_dialog_run(GTK_DIALOG(dialog));
758 switch(response) {
760 case GTK_RESPONSE_REJECT:
761 loop = FALSE;
762 break;
763 case GTK_RESPONSE_ACCEPT:
764 loop = FALSE;
765 break;
766 case REMOVE_COMMAND:
767 remove_command(self);
768 break;
769 case ADD_COMMAND:
770 add_command(self);
771 break;
776 }while(loop);
779 gtk_widget_destroy(GTK_WIDGET(dialog));
782 void telnet_command_edited_callback(GtkCellRendererText *renderer,
783 gchar *path_string,gchar *new_text,
784 TelnetBackend *self)
786 gint column;
787 GtkTreePath *path;
789 gboolean valid;
790 path = gtk_tree_path_new_from_string (path_string);
792 column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(renderer),"column"));
793 path = gtk_tree_path_new_from_string (path_string);
794 gtk_tree_model_get_iter (self->model, &self->iter, path);
796 switch(column)
798 case COL_CMD:
800 gint i;
801 gchar *old_text;
802 gtk_tree_model_get (self->model, &self->iter,
803 column, &old_text, -1);
804 g_free (old_text);
805 i = gtk_tree_path_get_indices (path)[0];
806 gtk_list_store_set (GTK_LIST_STORE (self->model),
807 &self->iter, column,new_text, -1);
810 break;
811 case COL_NAME:
814 gint i;
815 gchar *old_text;
816 gtk_tree_model_get (self->model, &self->iter, column,
817 &old_text, -1);
818 g_free (old_text);
819 i = gtk_tree_path_get_indices (path)[0];
820 gtk_list_store_set (GTK_LIST_STORE (self->model),
821 &self->iter, column,new_text, -1);
825 break;
828 valid = gtk_tree_model_get_iter_first (self->model, &self->iter);
831 void remove_command(TelnetBackend *self)
834 GtkTreeIter iter;
835 GtkTreeSelection *selection;
838 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(self->treeview));
839 if (gtk_tree_selection_get_selected (selection, NULL, &iter))
841 gtk_list_store_remove (GTK_LIST_STORE (self->model), &iter);
847 void add_command(TelnetBackend *self)
849 gtk_list_store_append(GTK_LIST_STORE(self->store), &self->iter);
850 gtk_list_store_set (GTK_LIST_STORE(self->store), &self->iter,
851 COL_NAME, "name",COL_CMD,"command",-1);
856 gchar *telnet_backend_get_description(gpointer instance_context)
858 return NULL;
861 IrrecoBackendStatus telnet_backend_create_device(gpointer instance_context,
862 GtkWindow * parent)
866 return IRRECO_BACKEND_OK;
868 IrrecoBackendStatus telnet_backend_delete_device(gpointer instance_context,
869 const gchar * device_name,
870 gpointer device_contex,
871 GtkWindow * parent)
874 return IRRECO_BACKEND_OK;
877 IrrecoBackendFunctionTable telnet_backend_function_table =
879 IRRECO_BACKEND_API_VERSION,
880 IRRECO_BACKEND_EDITABLE_DEVICES,
881 "Telnet",
882 (IrrecoBackendGetErrorMsg) telnet_backend_get_error_msg,
883 (IrrecoBackendCreate) telnet_backend_create,
884 (IrrecoBackendDestroy) telnet_backend_destroy,
885 (IrrecoBackendReadFromConf) telnet_backend_read_from_conf,
886 (IrrecoBackendSaveToConf) telnet_backend_save_to_conf,
887 (IrrecoBackendGetDevices) telnet_backend_get_devices,
888 (IrrecoBackendGetCommands) telnet_backend_get_commands,
889 (IrrecoBackendSendCommand) telnet_backend_send_command,
890 (IrrecoBackendConfigure) telnet_backend_configure,
891 (IrrecoBackendGetDescription) telnet_backend_get_description,
892 (IrrecoBackendCreateDevice) telnet_backend_create_device,
893 (IrrecoBackendIsDeviceEditable)telnet_backend_is_device_editable,
894 (IrrecoBackendEditDevice) telnet_backend_edit_device,
895 (IrrecoBackendDeleteDevice) telnet_backend_delete_device,NULL,NULL,NULL
898 IrrecoBackendFunctionTable *get_irreco_backend_function_table()
900 return &telnet_backend_function_table;