LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   adding UI to a console program (with source) (https://www.linuxquestions.org/questions/linux-newbie-8/adding-ui-to-a-console-program-with-source-365766/)

okeyla 09-21-2005 09:39 PM

adding UI to a console program (with source)
 
I have a shell script ,
and would like to add a UI on it. (I use FLTK)
Some buttons on UI will command to the console program.
The response of the console program will be displayed on UI.

Many recommand pipe is suitable.
Since it is uni-directional , so i have to establish 2 pipes.

UI -> pipe2 -> console program
<- pipe1 <-

User just face to UI and don't care about the console.


The following is my codes.
Now i do coding of the reading part , but cannot make it.
Could someone give me a hand?

Code:


[menu.sh]
#!/bin/bash
let "loop=0"
while test $loop == 0
do
echo "Please choose the letter of the game you want to run and  enter"
echo "------------------------------------------------------"
echo "a. Checking files"
echo "b. PWD"
echo "c. Adding string to file"
echo "------------------------------------------------------"
echo "q. quit"
echo "choice?"
read choice

case $choice in q)
let "loop=1"
esac
case $choice in a)
clear
echo "You are checking the files of this directory!"
ls -al
esac
case $choice in b)
clear
echo "You are checking the current directory"
pwd
esac
case $choice in c)
clear
echo "You are adding string to a file"
echo "I am number1" >> text.txt
esac
done

[fltk_popen_demo.cxx]
// demo use of popen() and Fl::add_fd() - erco 10/04/04
#include <stdio.h>
#include <stdlib.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Multi_Browser.H>

#include <unistd.h>

FILE *G_fp = NULL;

void HandleFD(int fd, void *data) {
    Fl_Multi_Browser *brow = (Fl_Multi_Browser*)data;
    char s[1024];
    if ( fgets(s, 1023, G_fp) == NULL ) {
        Fl::remove_fd(fileno(G_fp));
        pclose(G_fp);
        return;
    }
    brow->add(s);
}

int main() {

    system("sh runme1.sh");

    Fl_Window win(600,600);
    Fl_Multi_Browser brow(10,10,580,580);
    if ( ( G_fp = popen("cat < pipe1", "r" ) ) == NULL ) {
        perror("popen failed");
        return(1);
    }
    Fl::add_fd(fileno(G_fp), HandleFD, (void*)&brow);
    win.resizable(brow);
    win.show();
    return(Fl::run());
}


[runme1.sh]
#!/bin/sh
if [ ! -e pipe1 ];then
mknod pipe1 p
fi
if [ ! -e pipe2 ];then
mknod pipe2 p
fi
sh ./menu.sh >pipe1 <pipe2


okeyla 09-22-2005 08:04 AM

change in fifo way
 
Now i use fifo to solve the problem above:

Code:

[menu.sh]
#!/bin/bash
while [ 1 ]; do
    echo ""
    echo "Menu Options"
    echo "    a) Do an ls -la"
    echo "    b) netstat -r"
    echo "    c) date/who"
    echo "    q) quit"
    echo ""
    echo "Your choice?"
    read choice
    if [ ! $? ]; then echo 'Parent closed'; exit 1; fi
    case $choice in
        q) exit 0 ;;
        a) ls -la ;;
        b) netstat -r ;;
        c) date; w ;;
    esac
done


[demo-fifo.cxx]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>  // mkfifo
#include <sys/stat.h>  // mkfifo
#include <fcntl.h>      // open
#include <signal.h>    // killpg

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Multi_Browser.H>
#include <FL/Fl_Button.H>

//
// Demonstrate how to use fltk with named pipes
// erco 1.00 09/21/2005
//

// Globals
FILE *G_in = NULL;              // how we read the child
int  G_out = 0;                // how we write to the child

// Close all descriptors, remove fifo
void CleanExit_CB(Fl_Widget*, void *data) {
    unlink("tomenu.fifo");
    killpg(getpid(), SIGKILL);
    _exit(0);
}

// Read output from child, append to browser
void HandleInput_CB(int, void *data) {
    Fl_Multi_Browser *brow = (Fl_Multi_Browser*)data;
    char s[1024];
    if ( fgets(s, 1023, G_in) == NULL ) {
        CleanExit_CB(0,0);
    }
    brow->add(s);
}

// Handle sending commands to child when button pressed
void HandleButton_CB(Fl_Widget*, void *data) {
    char *msg = (char*)data;
    write(G_out, (char*)msg, strlen(msg));
}

int main() {
    // Process group leader (for killpg())
    setsid();
    // Make fifo
    unlink("tomenu.fifo");
    if ( mkfifo("tomenu.fifo", 0666) < 0 ) {
        perror("mkfifo(tomenu.fifo)");
        exit(1);
    }
    // Popen child for reading, set child to read fifo
    if ( ( G_in = popen("./menu.sh < tomenu.fifo", "r") ) == NULL ) {
        perror("popen failed");
        exit(1);
    }
    setbuf(G_in, NULL);        // disable buffering
    // Now open fifo
    if ( ( G_out = open("tomenu.fifo", O_WRONLY) ) < 0 ) {
        perror("open(tomenu.fifo) for write failed");
        unlink("tomenu.fifo");
        exit(1);
    }
    Fl_Window win(600,600);
    win.callback(CleanExit_CB);
    Fl_Button a(10, 10, 20, 20, "A"); a.callback(HandleButton_CB, (void*)"a\n");
    Fl_Button b(30, 10, 20, 20, "B"); b.callback(HandleButton_CB, (void*)"b\n");
    Fl_Button c(50, 10, 20, 20, "C"); c.callback(HandleButton_CB, (void*)"c\n");
    Fl_Multi_Browser brow(10,30,580,560);
    brow.textfont(FL_COURIER);
    Fl::add_fd(fileno(G_in), HandleInput_CB, (void*)&brow);
    win.resizable(brow);
    win.show();
    return(Fl::run());
}


But if i change the script to a console mode program,
it would fail... >_<

for example,
linphonec is a console mode VoIP program.
http://simon.morlat.free.fr/download/0.12.2/rpm/

Code:

[demo_fifo.cxx] no change!
[menu.sh] run the linphonec in background
#!/bin/sh
linphonec &

Could anyone give me a hand???


All times are GMT -5. The time now is 02:23 PM.