mirror of https://github.com/tLDP/LDP
add
This commit is contained in:
parent
58f2f857e0
commit
f4d6ab3707
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,45 @@
|
|||
This directory is structured as follows:
|
||||
|
||||
LDP/howto/docbook/NCURSES-HOWTO
|
||||
|
|
||||
|----> NCURSES-Programming-HOWTO.sgml -- the sgml source of the howto
|
||||
|----> ncurses_programs -- directory containing example
|
||||
| -- programs. See README in the
|
||||
| -- directory for details
|
||||
|----> ncurses_programs.tar.gz -- tar, gzipped programs. Generated
|
||||
| -- with command
|
||||
| -- tar --exclude CVS -cvf ncurses_programs.tar.gz
|
||||
| -- ncurses_programs/*
|
||||
|----> insert.pl -- a script used to remove inlined programs
|
||||
| -- it is used only once.
|
||||
|----> README -- this file
|
||||
|
||||
Bulding from source
|
||||
-------------------
|
||||
If you are planning to download the sgml source and build various formats
|
||||
of the document, follow these instructions.
|
||||
|
||||
Get both the source and the tar,gzipped programs, available at
|
||||
http://cvsview.tldp.org/index.cgi/LDP/howto/docbook/
|
||||
NCURSES-HOWTO/NCURSES-Programming-HOWTO.sgml
|
||||
http://cvsview.tldp.org/index.cgi/LDP/howto/docbook/
|
||||
NCURSES-HOWTO/ncurses_programs.tar.gz
|
||||
|
||||
Unzip ncurses_programs.tar.gz with
|
||||
tar zxvf ncurses_programs.tar.gz
|
||||
|
||||
Use jade to create various formats. For example if you just want to create
|
||||
the multiple html files, you would use
|
||||
jade -t sgml -i html -d <path to docbook html stylesheet>
|
||||
NCURSES-Programming-HOWTO.sgml
|
||||
to get pdf, first create a single html file of the HOWTO with
|
||||
jade -t sgml -i html -d <path to docbook html stylesheet> -V nochunks
|
||||
NCURSES-Programming-HOWTO.sgml > NCURSES-ONE-BIG-FILE.html
|
||||
then use htmldoc to get pdf file with
|
||||
htmldoc --size universal -t pdf --firstpage p1 -f <output file name.pdf>
|
||||
NCURSES-ONE-BIG-FILE.html
|
||||
for ps, you would use
|
||||
htmldoc --size universal -t ps --firstpage p1 -f <output file name.ps>
|
||||
NCURSES-ONE-BIG-FILE.html
|
||||
|
||||
For more details on jade usage see the section on jade in LDP-Author-Guide
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/local/bin/perl
|
||||
# Converts the inline programlistings into filerefs
|
||||
# The original source should contain some thing like
|
||||
# <programlisting>
|
||||
# /* File Path: adir/filename */
|
||||
# ..
|
||||
# ..
|
||||
# ..
|
||||
# </programlisting>
|
||||
#
|
||||
# this gets converted to
|
||||
#
|
||||
# <programlisting><inlinemediaobject><imageobject>
|
||||
# <imagedata format="linespecific" fileref="adir/filename">
|
||||
# </imageobject></inlinemediaobject></programlisting>
|
||||
#
|
||||
|
||||
if(@ARGV != 1) {
|
||||
print "Usage: $0 <sgml source with programs inline>\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
open(ORIG, "<$ARGV[0]") || die("Cannot open input file");
|
||||
open(TMP, ">tmp.out");
|
||||
|
||||
$ready = 0;
|
||||
|
||||
while(<ORIG>) {
|
||||
chomp;
|
||||
|
||||
if(/^\<programlisting\>/) {
|
||||
$ready = 1;
|
||||
}
|
||||
elsif ($ready == 1) {
|
||||
if(/^\/\*.*:\s([\w\/\.]+)\s/) {
|
||||
print TMP "<programlisting><inlinemediaobject><imageobject>\n";
|
||||
print TMP " <imagedata format=\"linespecific\" \
|
||||
fileref=\"ncurses_programs/$1\">\n";
|
||||
$ready = 2;
|
||||
}
|
||||
else {
|
||||
print TMP "<programlisting>\n";
|
||||
print TMP "$_\n";
|
||||
$ready = 0;
|
||||
}
|
||||
}
|
||||
elsif($ready == 2 && /\<\/programlisting\>/) {
|
||||
print TMP "</imageobject></inlinemediaobject></programlisting>\n";
|
||||
$ready = 0;
|
||||
}
|
||||
elsif($ready != 2) {
|
||||
print TMP $_, "\n";
|
||||
next;
|
||||
}
|
||||
}
|
||||
close(TMP);
|
||||
close(ORIG);
|
||||
|
||||
#system("mv tmp.out $ARGV[0]");
|
Binary file not shown.
|
@ -0,0 +1,18 @@
|
|||
Copyright (c) 2001, Pradeep Padala.
|
||||
|
||||
All the programs in this directory and sub directories are free
|
||||
software; you can redistribute them and/or modify them under the
|
||||
terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
|
||||
Please send comments to p_padala@yahoo.com
|
|
@ -0,0 +1,28 @@
|
|||
# Makefile for JustForFun Files
|
||||
|
||||
# A few variables
|
||||
|
||||
CC=gcc
|
||||
LIBS=-lncurses
|
||||
|
||||
SRC_DIR=.
|
||||
EXE_DIR=../demo/exe
|
||||
|
||||
EXES = \
|
||||
${EXE_DIR}/hanoi \
|
||||
${EXE_DIR}/life\
|
||||
${EXE_DIR}/magic \
|
||||
${EXE_DIR}/queens \
|
||||
${EXE_DIR}/shuffle \
|
||||
${EXE_DIR}/tt
|
||||
|
||||
${EXE_DIR}/%: %.o
|
||||
${CC} -o $@ $< ${LIBS}
|
||||
|
||||
%.o: ${SRC_DIR}/%.c
|
||||
${CC} -o $@ -c $<
|
||||
|
||||
all: ${EXES}
|
||||
|
||||
clean:
|
||||
@rm -f ${EXES}
|
|
@ -0,0 +1,10 @@
|
|||
Description of files
|
||||
--------------------
|
||||
JustForFun
|
||||
|
|
||||
|----> hanoi.c -- The Towers of Hanoi Solver
|
||||
|----> life.c -- The Game of Life demo
|
||||
|----> magic.c -- An Odd Order Magic Square builder
|
||||
|----> queens.c -- The famous N-Queens Solver
|
||||
|----> shuffle.c -- A fun game, if you have time to kill
|
||||
|----> tt.c -- A very trivial typing tutor
|
|
@ -0,0 +1,178 @@
|
|||
#include <curses.h>
|
||||
|
||||
#define POSX 10
|
||||
#define POSY 5
|
||||
#define DISC_CHAR '*'
|
||||
#define PEG_CHAR '#'
|
||||
#define TIME_OUT 300
|
||||
|
||||
typedef struct _peg_struct {
|
||||
int n_discs; /* Number of discs at present */
|
||||
int bottomx, bottomy; /* bottom x, bottom y co-ord */
|
||||
int *sizes; /* The disc sizes array */
|
||||
}peg;
|
||||
|
||||
void init_pegs(peg *p_my_pegs, int n_discs);
|
||||
void show_pegs(WINDOW *win, peg *p_my_pegs, int n_discs);
|
||||
void free_pegs(peg *p_my_pegs, int n_discs);
|
||||
void solve_hanoi(peg *p_my_pegs, int n, int src, int aux, int dst);
|
||||
void move_disc(peg *p_my_pegs, int n_discs, int src, int dst);
|
||||
void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win);
|
||||
void check_usr_response(peg *p_my_pegs, int n_discs);
|
||||
|
||||
int store_n_discs;
|
||||
char *welcome_string = "Enter the number of discs you want to be solved: ";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ int n_discs;
|
||||
peg my_pegs[3];
|
||||
|
||||
initscr(); /* Start curses mode */
|
||||
cbreak(); /* Line buffering disabled. Pass on every thing */
|
||||
keypad(stdscr, TRUE);
|
||||
curs_set(FALSE);
|
||||
|
||||
print_in_middle(0, LINES / 2, COLS, welcome_string, NULL);
|
||||
scanw("%d", &n_discs);
|
||||
|
||||
timeout(TIME_OUT);
|
||||
noecho();
|
||||
store_n_discs = n_discs;
|
||||
|
||||
init_pegs(my_pegs, n_discs);
|
||||
show_pegs(stdscr, my_pegs, n_discs);
|
||||
solve_hanoi(my_pegs, n_discs, 0, 1, 2);
|
||||
|
||||
free_pegs(my_pegs, n_discs);
|
||||
endwin(); /* End curses mode */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void solve_hanoi(peg *p_my_pegs, int n_discs, int src, int aux, int dst)
|
||||
{ if(n_discs == 0)
|
||||
return;
|
||||
solve_hanoi(p_my_pegs, n_discs - 1, src, dst, aux);
|
||||
move_disc(p_my_pegs, store_n_discs, src, dst);
|
||||
show_pegs(stdscr, p_my_pegs, store_n_discs);
|
||||
check_usr_response(p_my_pegs, store_n_discs);
|
||||
solve_hanoi(p_my_pegs, n_discs - 1, aux, src, dst);
|
||||
}
|
||||
|
||||
void check_usr_response(peg *p_my_pegs, int n_discs)
|
||||
{ int ch;
|
||||
|
||||
ch = getch(); /* Waits for TIME_OUT milliseconds */
|
||||
if(ch == ERR)
|
||||
return;
|
||||
else
|
||||
if(ch == KEY_F(1))
|
||||
{ free_pegs(p_my_pegs, n_discs);
|
||||
endwin();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void move_disc(peg *p_my_pegs, int n_discs, int src, int dst)
|
||||
{ int temp, index;
|
||||
|
||||
--p_my_pegs[src].n_discs;
|
||||
index = 0;
|
||||
while(p_my_pegs[src].sizes[index] == 0 && index != n_discs)
|
||||
++index;
|
||||
temp = p_my_pegs[src].sizes[index];
|
||||
p_my_pegs[src].sizes[index] = 0;
|
||||
|
||||
index = 0;
|
||||
while(p_my_pegs[dst].sizes[index] == 0 && index != n_discs)
|
||||
++index;
|
||||
--index;
|
||||
p_my_pegs[dst].sizes[index] = temp;
|
||||
++p_my_pegs[dst].n_discs;
|
||||
}
|
||||
|
||||
void init_pegs(peg *p_my_pegs, int n_discs)
|
||||
{ int size, temp, i;
|
||||
|
||||
p_my_pegs[0].n_discs = n_discs;
|
||||
|
||||
/* Allocate memory for size array
|
||||
* atmost the number of discs on a peg can be n_discs
|
||||
*/
|
||||
for(i = 0; i < n_discs; ++i)
|
||||
p_my_pegs[i].sizes = (int *)calloc(n_discs, sizeof(int));
|
||||
size = 3;
|
||||
for(i = 0;i < n_discs; ++i, size += 2)
|
||||
p_my_pegs[0].sizes[i] = size;
|
||||
|
||||
temp = (p_my_pegs[0].sizes[n_discs - 1] / 2);
|
||||
p_my_pegs[0].bottomx = POSX + 1 + temp;
|
||||
p_my_pegs[0].bottomy = POSY + 2 + n_discs;
|
||||
|
||||
p_my_pegs[1].bottomx = p_my_pegs[0].bottomx + 2 + 2 * temp;
|
||||
p_my_pegs[1].bottomy = POSY + 2 + n_discs;
|
||||
|
||||
p_my_pegs[2].bottomx = p_my_pegs[1].bottomx + 2 + 2 * temp;
|
||||
p_my_pegs[2].bottomy = POSY + 2 + n_discs;
|
||||
}
|
||||
|
||||
void show_pegs(WINDOW *win, peg *p_my_pegs, int n_discs)
|
||||
{ int i, j, k, x, y, size;
|
||||
|
||||
wclear(win);
|
||||
attron(A_REVERSE);
|
||||
mvprintw(24, 0, "Press F1 to Exit");
|
||||
attroff(A_REVERSE);
|
||||
for(i = 0;i < 3; ++i)
|
||||
mvwprintw( win, p_my_pegs[i].bottomy - n_discs - 1,
|
||||
p_my_pegs[i].bottomx, "%c", PEG_CHAR);
|
||||
y = p_my_pegs[0].bottomy - n_discs;
|
||||
for(i = 0; i < 3; ++i) /* For each peg */
|
||||
{ for(j = 0; j < n_discs; ++ j) /* For each row */
|
||||
{ if(p_my_pegs[i].sizes[j] != 0)
|
||||
{ size = p_my_pegs[i].sizes[j];
|
||||
x = p_my_pegs[i].bottomx - (size / 2);
|
||||
for(k = 0; k < size; ++k)
|
||||
mvwprintw(win, y, x + k, "%c", DISC_CHAR);
|
||||
}
|
||||
else
|
||||
mvwprintw(win, y, p_my_pegs[i].bottomx, "%c", PEG_CHAR);
|
||||
++y;
|
||||
}
|
||||
y = p_my_pegs[0].bottomy - n_discs;
|
||||
}
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
void free_pegs(peg *p_my_pegs, int n_discs)
|
||||
{ int i;
|
||||
|
||||
for(i = 0;i < n_discs; ++i)
|
||||
free(p_my_pegs[i].sizes);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------*
|
||||
* startx = 0 means at present x *
|
||||
* starty = 0 means at present y *
|
||||
* win = NULL means take stdscr *
|
||||
* -------------------------------------------------------------*/
|
||||
|
||||
void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
#include <curses.h>
|
||||
|
||||
int STARTX = 0;
|
||||
int STARTY = 0;
|
||||
int ENDX = 79;
|
||||
int ENDY = 24;
|
||||
|
||||
#define CELL_CHAR '#'
|
||||
#define TIME_OUT 300
|
||||
|
||||
typedef struct _state {
|
||||
int oldstate;
|
||||
int newstate;
|
||||
}state;
|
||||
|
||||
void display(WINDOW *win, state **area, int startx, int starty, int endx, int endy);
|
||||
void calc(state **area, int x, int y);
|
||||
void update_state(state **area, int startx, int starty, int endx, int endy);
|
||||
|
||||
int main()
|
||||
{ state **workarea;
|
||||
int i, j;
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
timeout(TIME_OUT);
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
ENDX = COLS - 1;
|
||||
ENDY = LINES - 1;
|
||||
|
||||
workarea = (state **)calloc(COLS, sizeof(state *));
|
||||
for(i = 0;i < COLS; ++i)
|
||||
workarea[i] = (state *)calloc(LINES, sizeof(state));
|
||||
|
||||
/* For inverted U */
|
||||
workarea[39][15].newstate = TRUE;
|
||||
workarea[40][15].newstate = TRUE;
|
||||
workarea[41][15].newstate = TRUE;
|
||||
workarea[39][16].newstate = TRUE;
|
||||
workarea[39][17].newstate = TRUE;
|
||||
workarea[41][16].newstate = TRUE;
|
||||
workarea[41][17].newstate = TRUE;
|
||||
update_state(workarea, STARTX, STARTY, ENDX, ENDY);
|
||||
|
||||
/* For block */
|
||||
/*
|
||||
workarea[37][13].newstate = TRUE;
|
||||
workarea[37][14].newstate = TRUE;
|
||||
workarea[38][13].newstate = TRUE;
|
||||
workarea[38][14].newstate = TRUE;
|
||||
|
||||
update_state(workarea, STARTX, STARTY, ENDX, ENDY);
|
||||
*/
|
||||
display(stdscr, workarea, STARTX, STARTY, ENDX, ENDY);
|
||||
while(getch() != KEY_F(1))
|
||||
{ for(i = STARTX; i <= ENDX; ++i)
|
||||
for(j = STARTY; j <= ENDY; ++j)
|
||||
calc(workarea, i, j);
|
||||
update_state(workarea, STARTX, STARTY, ENDX, ENDY);
|
||||
display(stdscr, workarea, STARTX, STARTY, ENDX, ENDY);
|
||||
}
|
||||
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void display(WINDOW *win, state **area, int startx, int starty, int endx, int endy)
|
||||
{ int i, j;
|
||||
wclear(win);
|
||||
for(i = startx; i <= endx; ++i)
|
||||
for(j = starty;j <= endy; ++j)
|
||||
if(area[i][j].newstate == TRUE)
|
||||
mvwaddch(win, j, i, CELL_CHAR);
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
void calc(state **area, int i, int j)
|
||||
{ int neighbours;
|
||||
int newstate;
|
||||
|
||||
neighbours =
|
||||
area[(i - 1 + COLS) % COLS][j].oldstate +
|
||||
area[(i - 1 + COLS) % COLS][(j - 1 + LINES) % LINES].oldstate +
|
||||
area[(i - 1 + COLS) % COLS][(j + 1) % LINES].oldstate +
|
||||
area[(i + 1) % COLS][j].oldstate +
|
||||
area[(i + 1) % COLS][(j - 1 + LINES) % LINES].oldstate +
|
||||
area[(i + 1) % COLS][(j + 1) % LINES].oldstate +
|
||||
area[i][(j - 1 + LINES) % LINES].oldstate +
|
||||
area[i][(j + 1) % LINES].oldstate;
|
||||
|
||||
newstate = FALSE;
|
||||
if(area[i][j].oldstate == TRUE && (neighbours == 2 || neighbours == 3))
|
||||
newstate = TRUE;
|
||||
else
|
||||
if(area[i][j].oldstate == FALSE && neighbours == 3)
|
||||
newstate = TRUE;
|
||||
area[i][j].newstate = newstate;
|
||||
}
|
||||
|
||||
void update_state(state **area, int startx, int starty, int endx, int endy)
|
||||
{ int i, j;
|
||||
|
||||
for(i = startx; i <= endx; ++i)
|
||||
for(j = starty; j <= endy; ++j)
|
||||
area[i][j].oldstate = area[i][j].newstate;
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
#include <curses.h>
|
||||
|
||||
#define STARTX 9
|
||||
#define STARTY 3
|
||||
#define WIDTH 6
|
||||
#define HEIGHT 4
|
||||
|
||||
#define TRACE_VALUE TRACE_MAXIMUM
|
||||
|
||||
void board( WINDOW *win, int starty, int startx, int lines, int cols,
|
||||
int tile_width, int tile_height);
|
||||
void magic(int **, int);
|
||||
void print(int **, int);
|
||||
void magic_board(int **a,int n);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
int **a,n,i;
|
||||
|
||||
if(argc != 2)
|
||||
{ printf("Usage: %s <magic sqaure order>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
n = atoi(argv[1]);
|
||||
if(n % 2 == 0)
|
||||
{ printf("Sorry !!! I don't know how to create magic square of even order\n");
|
||||
printf("The order should be an odd number\n");
|
||||
exit(0);
|
||||
}
|
||||
a = (int **) malloc(n * sizeof(int*));
|
||||
for(i = 0;i < n;++i)
|
||||
a[i] = (int *)malloc(n * sizeof(int));
|
||||
|
||||
magic(a,n);
|
||||
|
||||
initscr();
|
||||
curs_set(0);
|
||||
noecho();
|
||||
magic_board(a,n);
|
||||
getch();
|
||||
endwin();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void magic(int **a, int n)
|
||||
{
|
||||
int i,j,k;
|
||||
int row,col;
|
||||
for(i = 0;i < n;++i)
|
||||
for(j = 0;j < n;++j)
|
||||
a[i][j] = -1;
|
||||
row = 0;
|
||||
col = n / 2;
|
||||
|
||||
k = 1;
|
||||
a[row][col] = k;
|
||||
|
||||
while(k != n * n)
|
||||
{
|
||||
if(row == 0 && col != n - 1)
|
||||
{ row = n - 1;
|
||||
col ++;
|
||||
a[row][col] = ++k;
|
||||
}
|
||||
else if(row != 0 && col != n - 1)
|
||||
{ if(a[row - 1][col + 1] == -1)
|
||||
{ row --;
|
||||
col ++;
|
||||
a[row][col] = ++k;
|
||||
}
|
||||
else
|
||||
{
|
||||
row ++;
|
||||
a[row][col] = ++k;
|
||||
}
|
||||
}
|
||||
else if(row != 0 && col == n - 1)
|
||||
{
|
||||
row --;
|
||||
col = 0;
|
||||
a[row][col] = ++k;
|
||||
}
|
||||
else if(row == 0 && col == n - 1)
|
||||
{ row ++;
|
||||
a[row][col] = ++k;
|
||||
}
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void print(int **a,int n)
|
||||
{ int i,j;
|
||||
int x,y;
|
||||
x = STARTX;
|
||||
y = STARTY;
|
||||
mvprintw(1,30,"MAGIC SQUARE");
|
||||
for(i = 0;i < n;++i)
|
||||
{ for(j = 0;j < n;++j)
|
||||
{ mvprintw(y,x,"%d",a[i][j]);
|
||||
if(n > 9)
|
||||
x += 4;
|
||||
else
|
||||
x += 6;
|
||||
}
|
||||
x = STARTX;
|
||||
if(n > 7)
|
||||
y += 2;
|
||||
else
|
||||
y += 3;
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
void board(WINDOW *win, int starty, int startx, int lines, int cols,
|
||||
int tile_width, int tile_height)
|
||||
{ int endy, endx, i, j;
|
||||
|
||||
endy = starty + lines * tile_height;
|
||||
endx = startx + cols * tile_width;
|
||||
|
||||
for(j = starty; j <= endy; j += tile_height)
|
||||
for(i = startx; i <= endx; ++i)
|
||||
mvwaddch(win, j, i, ACS_HLINE);
|
||||
for(i = startx; i <= endx; i += tile_width)
|
||||
for(j = starty; j <= endy; ++j)
|
||||
mvwaddch(win, j, i, ACS_VLINE);
|
||||
mvwaddch(win, starty, startx, ACS_ULCORNER);
|
||||
mvwaddch(win, endy, startx, ACS_LLCORNER);
|
||||
mvwaddch(win, starty, endx, ACS_URCORNER);
|
||||
mvwaddch(win, endy, endx, ACS_LRCORNER);
|
||||
for(j = starty + tile_height; j <= endy - tile_height; j += tile_height)
|
||||
{ mvwaddch(win, j, startx, ACS_LTEE);
|
||||
mvwaddch(win, j, endx, ACS_RTEE);
|
||||
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
|
||||
mvwaddch(win, j, i, ACS_PLUS);
|
||||
}
|
||||
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
|
||||
{ mvwaddch(win, starty, i, ACS_TTEE);
|
||||
mvwaddch(win, endy, i, ACS_BTEE);
|
||||
}
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
void magic_board(int **a,int n)
|
||||
{ int i,j, deltax, deltay;
|
||||
int startx, starty;
|
||||
|
||||
starty = (LINES - n * HEIGHT) / 2;
|
||||
startx = (COLS - n * WIDTH) / 2;
|
||||
board(stdscr, starty, startx, n, n, WIDTH, HEIGHT);
|
||||
deltay = HEIGHT / 2;
|
||||
deltax = WIDTH / 2;
|
||||
for(i = 0;i < n; ++i)
|
||||
for(j = 0; j < n; ++j)
|
||||
mvprintw(starty + j * HEIGHT + deltay,
|
||||
startx + i * WIDTH + deltax,
|
||||
"%d", a[i][j]);
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#include <stdio.h>
|
||||
#include <curses.h>
|
||||
|
||||
#define QUEEN_CHAR '*'
|
||||
|
||||
int *nqueens(int num);
|
||||
int place(int current, int *position);
|
||||
int print(int *positions, int num_queens);
|
||||
void board(WINDOW *win, int starty, int startx, int lines, int cols,
|
||||
int tile_width, int tile_height);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int num_queens, *positions, count;
|
||||
|
||||
if(argc != 2)
|
||||
{ printf("Usage: %s <number of queens (chess board order)>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
num_queens = atoi(argv[1]);
|
||||
initscr();
|
||||
cbreak();
|
||||
keypad(stdscr, TRUE);
|
||||
positions = nqueens(num_queens);
|
||||
free(positions);
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *nqueens(int num)
|
||||
{
|
||||
int current, *position, num_solutions = 0;
|
||||
|
||||
position = (int *) calloc(num + 1, sizeof(int));
|
||||
|
||||
position[1] = 0;
|
||||
current = 1; /* current queen is being checked */
|
||||
/* position[current] is the coloumn*/
|
||||
while(current > 0){
|
||||
position[current] += 1;
|
||||
while(position[current] <= num && !place(current, position) )
|
||||
position[current] += 1;
|
||||
if(position[current] <= num){
|
||||
if(current == num) {
|
||||
++num_solutions;
|
||||
print(position, num);
|
||||
}
|
||||
else {
|
||||
current += 1;
|
||||
position[current] = 0;
|
||||
}
|
||||
}
|
||||
else current -= 1; /* backtrack */
|
||||
}
|
||||
printf("Total Number of Solutions : %d\n", num_solutions);
|
||||
return(position);
|
||||
}
|
||||
|
||||
int place(int current, int *position)
|
||||
{
|
||||
int i;
|
||||
if(current == 1) return(1);
|
||||
for(i = 1; i < current; ++i)
|
||||
if(position[i] == position[current]) return(0);
|
||||
else if(abs(position[i] - position[current]) ==
|
||||
abs(i - current))
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
int print(int *positions, int num_queens)
|
||||
{ int count;
|
||||
int y = 2, x = 2, w = 4, h = 2;
|
||||
static int solution = 1;
|
||||
|
||||
mvprintw(0, 0, "Solution No: %d", solution++);
|
||||
board(stdscr, y, x, num_queens, num_queens, w, h);
|
||||
for(count = 1; count <= num_queens; ++count)
|
||||
{ int tempy = y + (count - 1) * h + h / 2;
|
||||
int tempx = x + (positions[count] - 1) * w + w / 2;
|
||||
mvaddch(tempy, tempx, QUEEN_CHAR);
|
||||
}
|
||||
refresh();
|
||||
mvprintw(LINES - 2, 0, "Press Any Key to See next solution (F1 to Exit)");
|
||||
if(getch() == KEY_F(1))
|
||||
{ endwin();
|
||||
exit(0);
|
||||
}
|
||||
clear();
|
||||
}
|
||||
|
||||
void board(WINDOW *win, int starty, int startx, int lines, int cols,
|
||||
int tile_width, int tile_height)
|
||||
{ int endy, endx, i, j;
|
||||
|
||||
endy = starty + lines * tile_height;
|
||||
endx = startx + cols * tile_width;
|
||||
|
||||
for(j = starty; j <= endy; j += tile_height)
|
||||
for(i = startx; i <= endx; ++i)
|
||||
mvwaddch(win, j, i, ACS_HLINE);
|
||||
for(i = startx; i <= endx; i += tile_width)
|
||||
for(j = starty; j <= endy; ++j)
|
||||
mvwaddch(win, j, i, ACS_VLINE);
|
||||
mvwaddch(win, starty, startx, ACS_ULCORNER);
|
||||
mvwaddch(win, endy, startx, ACS_LLCORNER);
|
||||
mvwaddch(win, starty, endx, ACS_URCORNER);
|
||||
mvwaddch(win, endy, endx, ACS_LRCORNER);
|
||||
for(j = starty + tile_height; j <= endy - tile_height; j += tile_height)
|
||||
{ mvwaddch(win, j, startx, ACS_LTEE);
|
||||
mvwaddch(win, j, endx, ACS_RTEE);
|
||||
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
|
||||
mvwaddch(win, j, i, ACS_PLUS);
|
||||
}
|
||||
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
|
||||
{ mvwaddch(win, starty, i, ACS_TTEE);
|
||||
mvwaddch(win, endy, i, ACS_BTEE);
|
||||
}
|
||||
wrefresh(win);
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
#include <curses.h>
|
||||
|
||||
#define STARTX 9
|
||||
#define STARTY 3
|
||||
#define WIDTH 6
|
||||
#define HEIGHT 4
|
||||
|
||||
#define BLANK 0
|
||||
|
||||
typedef struct _tile {
|
||||
int x;
|
||||
int y;
|
||||
}tile;
|
||||
|
||||
void init_board(int **board, int n, tile *blank);
|
||||
void board(WINDOW *win, int starty, int startx, int lines, int cols,
|
||||
int tile_width, int tile_height);
|
||||
void shuffle_board(int **board, int n);
|
||||
void move_blank(int direction, int **s_board, int n, tile *blank);
|
||||
int check_win(int **s_board, int n, tile *blank);
|
||||
|
||||
enum { LEFT, RIGHT, UP, DOWN };
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ int **s_board;
|
||||
int n, i, ch;
|
||||
tile blank;
|
||||
|
||||
if(argc != 2)
|
||||
{ printf("Usage: %s <shuffle board order>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
n = atoi(argv[1]);
|
||||
|
||||
s_board = (int **)calloc(n, sizeof(int *));
|
||||
for(i = 0;i < n; ++i)
|
||||
s_board[i] = (int *)calloc(n, sizeof(int));
|
||||
init_board(s_board, n, &blank);
|
||||
initscr();
|
||||
keypad(stdscr, TRUE);
|
||||
cbreak();
|
||||
shuffle_board(s_board, n);
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_LEFT:
|
||||
move_blank(RIGHT, s_board, n, &blank);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
move_blank(LEFT, s_board, n, &blank);
|
||||
break;
|
||||
case KEY_UP:
|
||||
move_blank(DOWN, s_board, n, &blank);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
move_blank(UP, s_board, n, &blank);
|
||||
break;
|
||||
}
|
||||
shuffle_board(s_board, n);
|
||||
if(check_win(s_board, n, &blank) == TRUE)
|
||||
{ mvprintw(24, 0, "You Win !!!\n");
|
||||
refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void move_blank(int direction, int **s_board, int n, tile *blank)
|
||||
{ int temp;
|
||||
|
||||
switch(direction)
|
||||
{ case LEFT:
|
||||
{ if(blank->x != 0)
|
||||
{ --blank->x;
|
||||
temp = s_board[blank->x][blank->y];
|
||||
s_board[blank->x + 1][blank->y] = temp;
|
||||
s_board[blank->x][blank->y] = BLANK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
{ if(blank->x != n - 1)
|
||||
{ ++blank->x;
|
||||
temp = s_board[blank->x][blank->y];
|
||||
s_board[blank->x - 1][blank->y] = temp;
|
||||
s_board[blank->x][blank->y] = BLANK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UP:
|
||||
{ if(blank->y != 0)
|
||||
{ --blank->y;
|
||||
temp = s_board[blank->x][blank->y];
|
||||
s_board[blank->x][blank->y + 1] = temp;
|
||||
s_board[blank->x][blank->y] = BLANK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DOWN:
|
||||
{ if(blank->y != n - 1)
|
||||
{ ++blank->y;
|
||||
temp = s_board[blank->x][blank->y];
|
||||
s_board[blank->x][blank->y - 1] = temp;
|
||||
s_board[blank->x][blank->y] = BLANK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int check_win(int **s_board, int n, tile *blank)
|
||||
{ int i, j;
|
||||
|
||||
s_board[blank->x][blank->y] = n * n;
|
||||
for(i = 0;i < n; ++i)
|
||||
for(j = 0;j < n; ++j)
|
||||
if(s_board[i][j] != j * n + i + 1)
|
||||
{ s_board[blank->x][blank->y] = BLANK;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s_board[blank->x][blank->y] = BLANK;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void init_board(int **s_board, int n, tile *blank)
|
||||
{ int i, j, k;
|
||||
int *temp_board;
|
||||
|
||||
temp_board = (int *)calloc(n * n, sizeof(int));
|
||||
srand(time(NULL));
|
||||
for(i = 0;i < n * n; ++i)
|
||||
{
|
||||
repeat :
|
||||
k = rand() % (n * n);
|
||||
for(j = 0;j <= i - 1; ++j)
|
||||
if (k == temp_board[j])
|
||||
goto repeat;
|
||||
else
|
||||
temp_board[i] = k;
|
||||
}
|
||||
k = 0;
|
||||
for (i = 0;i < n;++i)
|
||||
for(j = 0;j < n; ++j,++k)
|
||||
{ if(temp_board[k] == 0)
|
||||
{ blank->x = i;
|
||||
blank->y = j;
|
||||
}
|
||||
s_board[i][j] = temp_board[k];
|
||||
}
|
||||
free(temp_board);
|
||||
}
|
||||
|
||||
void board(WINDOW *win, int starty, int startx, int lines, int cols,
|
||||
int tile_width, int tile_height)
|
||||
{ int endy, endx, i, j;
|
||||
|
||||
endy = starty + lines * tile_height;
|
||||
endx = startx + cols * tile_width;
|
||||
|
||||
for(j = starty; j <= endy; j += tile_height)
|
||||
for(i = startx; i <= endx; ++i)
|
||||
mvwaddch(win, j, i, ACS_HLINE);
|
||||
for(i = startx; i <= endx; i += tile_width)
|
||||
for(j = starty; j <= endy; ++j)
|
||||
mvwaddch(win, j, i, ACS_VLINE);
|
||||
mvwaddch(win, starty, startx, ACS_ULCORNER);
|
||||
mvwaddch(win, endy, startx, ACS_LLCORNER);
|
||||
mvwaddch(win, starty, endx, ACS_URCORNER);
|
||||
mvwaddch(win, endy, endx, ACS_LRCORNER);
|
||||
for(j = starty + tile_height; j <= endy - tile_height; j += tile_height)
|
||||
{ mvwaddch(win, j, startx, ACS_LTEE);
|
||||
mvwaddch(win, j, endx, ACS_RTEE);
|
||||
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
|
||||
mvwaddch(win, j, i, ACS_PLUS);
|
||||
}
|
||||
for(i = startx + tile_width; i <= endx - tile_width; i += tile_width)
|
||||
{ mvwaddch(win, starty, i, ACS_TTEE);
|
||||
mvwaddch(win, endy, i, ACS_BTEE);
|
||||
}
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
void shuffle_board(int **s_board, int n)
|
||||
{ int i,j, deltax, deltay;
|
||||
int startx, starty;
|
||||
|
||||
starty = (LINES - n * HEIGHT) / 2;
|
||||
startx = (COLS - n * WIDTH) / 2;
|
||||
clear();
|
||||
mvprintw(24, 0, "Press F1 to Exit");
|
||||
board(stdscr, starty, startx, n, n, WIDTH, HEIGHT);
|
||||
deltay = HEIGHT / 2;
|
||||
deltax = WIDTH / 2;
|
||||
for(j = 0; j < n; ++j)
|
||||
for(i = 0;i < n; ++i)
|
||||
if(s_board[i][j] != BLANK)
|
||||
mvprintw(starty + j * HEIGHT + deltay,
|
||||
startx + i * WIDTH + deltax,
|
||||
"%-2d", s_board[i][j]);
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
#include <curses.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define HSIZE 60
|
||||
#define LENGTH 75
|
||||
#define WIDTH 10
|
||||
#define STARTX 1
|
||||
#define STARTY 5
|
||||
#define STATUSX 1
|
||||
#define STATUSY 25
|
||||
|
||||
#define KEY_F1 265
|
||||
|
||||
int print_menu();
|
||||
void print_byebye();
|
||||
void create_test_string();
|
||||
void print_time(time_t startt, time_t endt, int mistakes);
|
||||
void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win);
|
||||
|
||||
char *groups[] = { "`123456" ,
|
||||
"7890-=" ,
|
||||
"~!@#$%^" ,
|
||||
"&*()_+" ,
|
||||
"<>?" ,
|
||||
",./\\" ,
|
||||
"asdfg",
|
||||
"jkl;'",
|
||||
"qwer",
|
||||
"uiop",
|
||||
"tyur",
|
||||
"zxcv",
|
||||
"bnm",
|
||||
};
|
||||
int n_groups;
|
||||
|
||||
int main()
|
||||
{ int choice, i;
|
||||
char *test_array;
|
||||
int ch = KEY_F1;
|
||||
int mistakes;
|
||||
int x, y;
|
||||
time_t start_t, end_t;
|
||||
WINDOW *typing_win;
|
||||
char string[80];
|
||||
|
||||
string[0] = '\0';
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
intrflush(stdscr, FALSE);
|
||||
|
||||
srandom(time(NULL));
|
||||
n_groups = sizeof(groups) / sizeof(char *);
|
||||
test_array = (char *)calloc(HSIZE + 1, sizeof(char));
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(ch == KEY_F1)
|
||||
{ choice = print_menu();
|
||||
choice -= 1;
|
||||
if(choice == n_groups)
|
||||
{ print_byebye();
|
||||
free(test_array);
|
||||
endwin();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
clear();
|
||||
strcpy(string, "Typing window");
|
||||
print_in_middle(STARTX, STARTY - 2, LENGTH, string, NULL);
|
||||
attron(A_REVERSE);
|
||||
mvprintw(STATUSY, STATUSX, "Press F1 to Main Menu");
|
||||
refresh();
|
||||
attroff(A_REVERSE);
|
||||
|
||||
create_test_string(test_array, choice);
|
||||
typing_win = newwin(WIDTH, LENGTH, STARTY, STARTX);
|
||||
keypad(typing_win, TRUE);
|
||||
intrflush(typing_win, FALSE);
|
||||
box(typing_win, 0, 0);
|
||||
|
||||
x = 1;
|
||||
y = 1;
|
||||
mvwprintw(typing_win, y, x, "%s", test_array);
|
||||
wrefresh(typing_win);
|
||||
y += 1;
|
||||
|
||||
mistakes = 0;
|
||||
i = 0;
|
||||
time(&start_t);
|
||||
wmove(typing_win, y, x);
|
||||
wrefresh(typing_win);
|
||||
ch = 0;
|
||||
while(ch != KEY_F1 && i != HSIZE + 1)
|
||||
{ ch = wgetch(typing_win);
|
||||
mvwprintw(typing_win, y, x, "%c", ch);
|
||||
wrefresh(typing_win);
|
||||
++x;
|
||||
if(ch == test_array[i])
|
||||
{ ++i;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ ++mistakes;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
time(&end_t);
|
||||
print_time(start_t, end_t, mistakes);
|
||||
}
|
||||
free(test_array);
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int print_menu()
|
||||
{ int choice, i;
|
||||
|
||||
choice = 0;
|
||||
while(1)
|
||||
{ clear();
|
||||
printw("\n\n");
|
||||
print_in_middle(1, 1, 0, "* * * Welcome to typing practice (Version 1.0) * * * ", NULL);
|
||||
printw("\n\n\n");
|
||||
for(i = 0;i <= n_groups - 1; ++i)
|
||||
printw("\t%3d: \tPractice %s\n", i + 1, groups[i]);
|
||||
printw("\t%3d: \tExit\n", i + 1);
|
||||
|
||||
printw("\n\n\tChoice: ");
|
||||
refresh();
|
||||
echo();
|
||||
scanw("%d", &choice);
|
||||
noecho();
|
||||
|
||||
if(choice >= 1 && choice <= n_groups + 1)
|
||||
break;
|
||||
else
|
||||
{ attron(A_REVERSE);
|
||||
mvprintw(STATUSY, STATUSX, "Wrong choice\tPress any key to continue");
|
||||
attroff(A_REVERSE);
|
||||
getch();
|
||||
}
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
|
||||
void create_test_string(char *test_array, int choice)
|
||||
{ int i, index, length;
|
||||
|
||||
length = strlen(groups[choice]);
|
||||
for(i = 0;i <= HSIZE - 1; ++i)
|
||||
{ if(i%5 == 0)
|
||||
test_array[i] = ' ';
|
||||
else
|
||||
{ index = (int)(random() % length);
|
||||
test_array[i] = groups[choice][index];
|
||||
}
|
||||
}
|
||||
test_array[i] = '\0';
|
||||
}
|
||||
|
||||
void print_byebye()
|
||||
{ printw("\n");
|
||||
print_in_middle(0,0,0,"Thank you for using my typing tutor\n", NULL);
|
||||
print_in_middle(0,0,0,"Bye Bye ! ! !\n", NULL);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void print_time(time_t start_t, time_t end_t, int mistakes)
|
||||
{ long int diff;
|
||||
int h,m,s;
|
||||
float wpm;
|
||||
|
||||
diff = end_t - start_t;
|
||||
wpm = ((HSIZE / 5)/(double)diff)*60;
|
||||
|
||||
h = (int)(diff / 3600);
|
||||
diff -= h * 3600;
|
||||
m = (int)(diff / 60);
|
||||
diff -= m * 60;
|
||||
s = (int)diff;
|
||||
|
||||
attron(A_REVERSE);
|
||||
mvprintw(STATUSY, STATUSX, "Mistakes made : %d time taken: %d:%d:%d WPM : %.2f Press any Key to continue", mistakes, h, m, s, wpm);
|
||||
attroff(A_REVERSE);
|
||||
|
||||
refresh();
|
||||
getch();
|
||||
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* startx = 0 means at present x *
|
||||
* starty = 0 means at present y *
|
||||
* win = NULL means take stdscr *
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# The top level Makefile
|
||||
|
||||
all:
|
||||
cd JustForFun && $(MAKE)
|
||||
cd basics && $(MAKE)
|
||||
cd forms && $(MAKE)
|
||||
cd menus && $(MAKE)
|
||||
cd panels && $(MAKE)
|
||||
@echo
|
||||
@echo "*********************************************"
|
||||
@echo "All files Built"
|
||||
@echo "Please move to demo/exe directory"
|
||||
@echo "Execute each file to see examples in action"
|
||||
@echo "*********************************************"
|
||||
@echo
|
||||
clean:
|
||||
cd JustForFun && $(MAKE) clean
|
||||
cd basics && $(MAKE) clean
|
||||
cd forms && $(MAKE) clean
|
||||
cd menus && $(MAKE) clean
|
||||
cd panels && $(MAKE) clean
|
|
@ -0,0 +1,82 @@
|
|||
This is the top level README file.
|
||||
This directory is structured as follows:
|
||||
|
||||
ncurses
|
||||
|
|
||||
|----> JustForFun -- just for fun programs
|
||||
|----> basics -- basic programs
|
||||
|----> demo -- output files go into this directory after make
|
||||
| |
|
||||
| |----> exe -- exe files of all example programs
|
||||
|----> forms -- programs related to form library
|
||||
|----> menus -- programs related to menus library
|
||||
|----> panels -- programs related to panels library
|
||||
|----> Makefile -- the top level Makefile
|
||||
|----> README -- the top level README file. contains instructions
|
||||
| -- to create executables for example programs
|
||||
|
||||
To compile and install all example programs, just run make in this directory.
|
||||
|
||||
make
|
||||
|
||||
It installs all the exe files in demo/exe directory. You can go to that direcory
|
||||
and see the examples in action.
|
||||
|
||||
Have Fun !!!
|
||||
-- Pradeep Padala
|
||||
|
||||
Description of files in each directory
|
||||
--------------------------------------
|
||||
JustForFun
|
||||
|
|
||||
|----> hanoi.c -- The Towers of Hanoi Solver
|
||||
|----> life.c -- The Game of Life demo
|
||||
|----> magic.c -- An Odd Order Magic Square builder
|
||||
|----> queens.c -- The famous N-Queens Solver
|
||||
|----> shuffle.c -- A fun game, if you have time to kill
|
||||
|----> tt.c -- A very trivial typing tutor
|
||||
|
||||
basics
|
||||
|
|
||||
|----> acs_vars.c -- ACS_ variables example
|
||||
|----> hello_world.c -- Simple "Hello World" Program
|
||||
|----> init_func_example.c -- Initialization functions example
|
||||
|----> key_code.c -- Shows the scan code of the key pressed
|
||||
|----> mouse_menu.c -- A menu accessible by mouse
|
||||
|----> other_border.c -- Shows usage of other border functions apart
|
||||
| -- box()
|
||||
|----> printw_example.c -- A very simple printw() example
|
||||
|----> scanw_example.c -- A very simple getstr() example
|
||||
|----> simple_attr.c -- A program that can print a c file with comments
|
||||
| -- in attribute
|
||||
|----> simple_color.c -- A simple example demonstrating colors
|
||||
|----> simple_key.c -- A menu accessible with keyboard UP, DOWN arrows
|
||||
|----> temp_leave.c -- Demonstrates temporarily leaving curses mode
|
||||
|----> win_border.c -- Shows Creation of windows and borders
|
||||
|----> with_chgat.c -- chgat() usage example
|
||||
|
||||
forms
|
||||
|
|
||||
|----> form_attrib.c -- Usage of field attributes
|
||||
|----> form_options.c -- Usage of field options
|
||||
|----> form_simple.c -- A simple form example
|
||||
|----> form_win.c -- Demo of windows associated with forms
|
||||
|
||||
menus
|
||||
|
|
||||
|----> menu_attrib.c -- Usage of menu attributes
|
||||
|----> menu_item_data.c -- Usage of item_name() etc.. functions
|
||||
|----> menu_multi_column.c -- Creates multi columnar menus
|
||||
|----> menu_scroll.c -- Demonstrates scrolling capability of menus
|
||||
|----> menu_simple.c -- A simple menu accessed by arrow keys
|
||||
|----> menu_toggle.c -- Creates multi valued menus and explains
|
||||
| -- REQ_TOGGLE_ITEM
|
||||
|----> menu_userptr.c -- Usage of user pointer
|
||||
|----> menu_win.c -- Demo of windows associated with menus
|
||||
|
||||
panels
|
||||
|
|
||||
|----> panel_browse.c -- Panel browsing through tab. Usage of user pointer
|
||||
|----> panel_hide.c -- Hiding and Un hiding of panels
|
||||
|----> panel_resize.c -- Moving and resizing of panels
|
||||
|----> panel_simple.c -- A simple panel example
|
|
@ -0,0 +1,35 @@
|
|||
# Makefile for JustForFun Files
|
||||
|
||||
# A few variables
|
||||
|
||||
CC=gcc
|
||||
LIBS=-lncurses
|
||||
|
||||
SRC_DIR=.
|
||||
EXE_DIR=../demo/exe
|
||||
|
||||
EXES = \
|
||||
${EXE_DIR}/hello_world \
|
||||
${EXE_DIR}/init_func_example \
|
||||
${EXE_DIR}/key_code \
|
||||
${EXE_DIR}/mouse_menu \
|
||||
${EXE_DIR}/other_border \
|
||||
${EXE_DIR}/printw_example \
|
||||
${EXE_DIR}/scanw_example \
|
||||
${EXE_DIR}/simple_attr \
|
||||
${EXE_DIR}/simple_color \
|
||||
${EXE_DIR}/simple_key \
|
||||
${EXE_DIR}/temp_leave \
|
||||
${EXE_DIR}/win_border \
|
||||
${EXE_DIR}/with_chgat
|
||||
|
||||
${EXE_DIR}/%: %.o
|
||||
${CC} -o $@ $< ${LIBS}
|
||||
|
||||
%.o: ${SRC_DIR}/%.c
|
||||
${CC} -o $@ -c $<
|
||||
|
||||
all: ${EXES}
|
||||
|
||||
clean:
|
||||
@rm -f ${EXES}
|
|
@ -0,0 +1,20 @@
|
|||
Description of files
|
||||
--------------------
|
||||
basics
|
||||
|
|
||||
|----> acs_vars.c -- ACS_ variables example
|
||||
|----> hello_world.c -- Simple "Hello World" Program
|
||||
|----> init_func_example.c -- Initialization functions example
|
||||
|----> key_code.c -- Shows the scan code of the key pressed
|
||||
|----> mouse_menu.c -- A menu accessible by mouse
|
||||
|----> other_border.c -- Shows usage of other border functions apart
|
||||
| -- box()
|
||||
|----> printw_example.c -- A very simple printw() example
|
||||
|----> scanw_example.c -- A very simple getstr() example
|
||||
|----> simple_attr.c -- A program that can print a c file with comments
|
||||
| -- in attribute
|
||||
|----> simple_color.c -- A simple example demonstrating colors
|
||||
|----> simple_key.c -- A menu accessible with keyboard UP, DOWN arrows
|
||||
|----> temp_leave.c -- Demonstrates temporarily leaving curses mode
|
||||
|----> win_border.c -- Shows Creation of windows and borders
|
||||
|----> with_chgat.c -- chgat() usage example
|
|
@ -0,0 +1,44 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
initscr();
|
||||
|
||||
printw("Upper left corner "); addch(ACS_ULCORNER); printw("\n");
|
||||
printw("Lower left corner "); addch(ACS_LLCORNER); printw("\n");
|
||||
printw("Lower right corner "); addch(ACS_LRCORNER); printw("\n");
|
||||
printw("Tee pointing right "); addch(ACS_LTEE); printw("\n");
|
||||
printw("Tee pointing left "); addch(ACS_RTEE); printw("\n");
|
||||
printw("Tee pointing up "); addch(ACS_BTEE); printw("\n");
|
||||
printw("Tee pointing down "); addch(ACS_TTEE); printw("\n");
|
||||
printw("Horizontal line "); addch(ACS_HLINE); printw("\n");
|
||||
printw("Vertical line "); addch(ACS_VLINE); printw("\n");
|
||||
printw("Large Plus or cross over "); addch(ACS_PLUS); printw("\n");
|
||||
printw("Scan Line 1 "); addch(ACS_S1); printw("\n");
|
||||
printw("Scan Line 3 "); addch(ACS_S3); printw("\n");
|
||||
printw("Scan Line 7 "); addch(ACS_S7); printw("\n");
|
||||
printw("Scan Line 9 "); addch(ACS_S9); printw("\n");
|
||||
printw("Diamond "); addch(ACS_DIAMOND); printw("\n");
|
||||
printw("Checker board (stipple) "); addch(ACS_CKBOARD); printw("\n");
|
||||
printw("Degree Symbol "); addch(ACS_DEGREE); printw("\n");
|
||||
printw("Plus/Minus Symbol "); addch(ACS_PLMINUS); printw("\n");
|
||||
printw("Bullet "); addch(ACS_BULLET); printw("\n");
|
||||
printw("Arrow Pointing Left "); addch(ACS_LARROW); printw("\n");
|
||||
printw("Arrow Pointing Right "); addch(ACS_RARROW); printw("\n");
|
||||
printw("Arrow Pointing Down "); addch(ACS_DARROW); printw("\n");
|
||||
printw("Arrow Pointing Up "); addch(ACS_UARROW); printw("\n");
|
||||
printw("Board of squares "); addch(ACS_BOARD); printw("\n");
|
||||
printw("Lantern Symbol "); addch(ACS_LANTERN); printw("\n");
|
||||
printw("Solid Square Block "); addch(ACS_BLOCK); printw("\n");
|
||||
printw("Less/Equal sign "); addch(ACS_LEQUAL); printw("\n");
|
||||
printw("Greater/Equal sign "); addch(ACS_GEQUAL); printw("\n");
|
||||
printw("Pi "); addch(ACS_PI); printw("\n");
|
||||
printw("Not equal "); addch(ACS_NEQUAL); printw("\n");
|
||||
printw("UK pound sign "); addch(ACS_STERLING); printw("\n");
|
||||
|
||||
refresh();
|
||||
getch();
|
||||
endwin();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
initscr(); /* Start curses mode */
|
||||
printw("Hello World !!!"); /* Print Hello World */
|
||||
refresh(); /* Print it on to the real screen */
|
||||
getch(); /* Wait for user input */
|
||||
endwin(); /* End curses mode */
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main()
|
||||
{ int ch;
|
||||
|
||||
initscr(); /* Start curses mode */
|
||||
raw(); /* Line buffering disabled */
|
||||
keypad(stdscr, TRUE); /* We get F1, F2 etc.. */
|
||||
noecho(); /* Don't echo() while we do getch */
|
||||
|
||||
printw("Type any character to see it in bold\n");
|
||||
ch = getch(); /* If raw() hadn't been called
|
||||
* we have to press enter before it
|
||||
* gets to the program */
|
||||
if(ch == KEY_F(1)) /* Without keypad enabled this will */
|
||||
printw("F1 Key pressed");/* not get to us either */
|
||||
/* Without noecho() some ugly escape
|
||||
* charachters might have been printed
|
||||
* on screen */
|
||||
else
|
||||
{ printw("The pressed key is ");
|
||||
attron(A_BOLD);
|
||||
printw("%c", ch);
|
||||
attroff(A_BOLD);
|
||||
}
|
||||
refresh(); /* Print it on to the real screen */
|
||||
getch(); /* Wait for user input */
|
||||
endwin(); /* End curses mode */
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main()
|
||||
{ int ch;
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
ch = getch();
|
||||
endwin();
|
||||
printf("The key pressed is %d\n", ch);
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
#define WIDTH 30
|
||||
#define HEIGHT 10
|
||||
|
||||
int startx = 0;
|
||||
int starty = 0;
|
||||
|
||||
char *choices[] = { "Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Exit",
|
||||
};
|
||||
|
||||
int n_choices = sizeof(choices) / sizeof(char *);
|
||||
|
||||
void print_menu(WINDOW *menu_win, int highlight);
|
||||
void report_choice(int mouse_x, int mouse_y, int *p_choice);
|
||||
|
||||
int main()
|
||||
{ int c, choice = 0;
|
||||
WINDOW *menu_win;
|
||||
MEVENT event;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
clear();
|
||||
noecho();
|
||||
cbreak(); //Line buffering disabled. pass on everything
|
||||
|
||||
/* Try to put the window in the middle of screen */
|
||||
startx = (80 - WIDTH) / 2;
|
||||
starty = (24 - HEIGHT) / 2;
|
||||
|
||||
attron(A_REVERSE);
|
||||
mvprintw(23, 1, "Click on Exit to quit (Works best in a virtual console)");
|
||||
refresh();
|
||||
attroff(A_REVERSE);
|
||||
|
||||
/* Print the menu for the first time */
|
||||
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
|
||||
print_menu(menu_win, 1);
|
||||
/* Get all the mouse events */
|
||||
mousemask(ALL_MOUSE_EVENTS, NULL);
|
||||
|
||||
while(1)
|
||||
{ c = wgetch(menu_win);
|
||||
switch(c)
|
||||
{ case KEY_MOUSE:
|
||||
if(getmouse(&event) == OK)
|
||||
{ /* When the user clicks left mouse button */
|
||||
if(event.bstate & BUTTON1_PRESSED)
|
||||
{ report_choice(event.x + 1, event.y + 1, &choice);
|
||||
if(choice == -1) //Exit chosen
|
||||
goto end;
|
||||
mvprintw(22, 1, "Choice made is : %d String Chosen is \"%10s\"", choice, choices[choice - 1]);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
print_menu(menu_win, choice);
|
||||
break;
|
||||
}
|
||||
}
|
||||
end:
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_menu(WINDOW *menu_win, int highlight)
|
||||
{
|
||||
int x, y, i;
|
||||
|
||||
x = 2;
|
||||
y = 2;
|
||||
box(menu_win, 0, 0);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
{ if(highlight == i + 1)
|
||||
{ wattron(menu_win, A_REVERSE);
|
||||
mvwprintw(menu_win, y, x, "%s", choices[i]);
|
||||
wattroff(menu_win, A_REVERSE);
|
||||
}
|
||||
else
|
||||
mvwprintw(menu_win, y, x, "%s", choices[i]);
|
||||
++y;
|
||||
}
|
||||
wrefresh(menu_win);
|
||||
}
|
||||
|
||||
/* Report the choice according to mouse position */
|
||||
void report_choice(int mouse_x, int mouse_y, int *p_choice)
|
||||
{ int i,j, choice;
|
||||
|
||||
i = startx + 2;
|
||||
j = starty + 3;
|
||||
|
||||
for(choice = 0; choice < n_choices; ++choice)
|
||||
if(mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice]))
|
||||
{ if(choice == n_choices - 1)
|
||||
*p_choice = -1;
|
||||
else
|
||||
*p_choice = choice + 1;
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
typedef struct _win_border_struct {
|
||||
chtype ls, rs, ts, bs,
|
||||
tl, tr, bl, br;
|
||||
}WIN_BORDER;
|
||||
|
||||
typedef struct _WIN_struct {
|
||||
|
||||
int startx, starty;
|
||||
int height, width;
|
||||
WIN_BORDER border;
|
||||
}WIN;
|
||||
|
||||
void init_win_params(WIN *p_win);
|
||||
void print_win_params(WIN *p_win);
|
||||
void create_box(WIN *win, int bool);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ WIN win;
|
||||
int ch;
|
||||
|
||||
initscr(); /* Start curses mode */
|
||||
start_color(); /* Start the color functionality */
|
||||
cbreak(); /* Line buffering disabled, Pass on
|
||||
* everty thing to me */
|
||||
keypad(stdscr, TRUE); /* I need that nifty F1 */
|
||||
noecho();
|
||||
init_pair(1, COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
/* Initialize the window parameters */
|
||||
init_win_params(&win);
|
||||
print_win_params(&win);
|
||||
|
||||
attron(COLOR_PAIR(1));
|
||||
printw("Press F1 to exit");
|
||||
refresh();
|
||||
attroff(COLOR_PAIR(1));
|
||||
|
||||
create_box(&win, TRUE);
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_LEFT:
|
||||
create_box(&win, FALSE);
|
||||
--win.startx;
|
||||
create_box(&win, TRUE);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
create_box(&win, FALSE);
|
||||
++win.startx;
|
||||
create_box(&win, TRUE);
|
||||
break;
|
||||
case KEY_UP:
|
||||
create_box(&win, FALSE);
|
||||
--win.starty;
|
||||
create_box(&win, TRUE);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
create_box(&win, FALSE);
|
||||
++win.starty;
|
||||
create_box(&win, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
endwin(); /* End curses mode */
|
||||
return 0;
|
||||
}
|
||||
void init_win_params(WIN *p_win)
|
||||
{
|
||||
p_win->height = 3;
|
||||
p_win->width = 10;
|
||||
p_win->starty = (LINES - p_win->height)/2;
|
||||
p_win->startx = (COLS - p_win->width)/2;
|
||||
|
||||
p_win->border.ls = '|';
|
||||
p_win->border.rs = '|';
|
||||
p_win->border.ts = '-';
|
||||
p_win->border.bs = '-';
|
||||
p_win->border.tl = '+';
|
||||
p_win->border.tr = '+';
|
||||
p_win->border.bl = '+';
|
||||
p_win->border.br = '+';
|
||||
|
||||
}
|
||||
void print_win_params(WIN *p_win)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
mvprintw(25, 0, "%d %d %d %d", p_win->startx, p_win->starty,
|
||||
p_win->width, p_win->height);
|
||||
refresh();
|
||||
#endif
|
||||
}
|
||||
void create_box(WIN *p_win, int bool)
|
||||
{ int i, j;
|
||||
int x, y, w, h;
|
||||
|
||||
x = p_win->startx;
|
||||
y = p_win->starty;
|
||||
w = p_win->width;
|
||||
h = p_win->height;
|
||||
|
||||
if(bool == TRUE)
|
||||
{ mvaddch(y, x, p_win->border.tl);
|
||||
mvaddch(y, x + w, p_win->border.tr);
|
||||
mvaddch(y + h, x, p_win->border.bl);
|
||||
mvaddch(y + h, x + w, p_win->border.br);
|
||||
mvhline(y, x + 1, p_win->border.ts, w - 1);
|
||||
mvhline(y + h, x + 1, p_win->border.bs, w - 1);
|
||||
mvvline(y + 1, x, p_win->border.ls, h - 1);
|
||||
mvvline(y + 1, x + w, p_win->border.rs, h - 1);
|
||||
|
||||
}
|
||||
else
|
||||
for(j = y; j <= y + h; ++j)
|
||||
for(i = x; i <= x + w; ++i)
|
||||
mvaddch(j, i, ' ');
|
||||
|
||||
refresh();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include <ncurses.h> /* ncurses.h includes stdio.h */
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char mesg[]="Just a string"; /* message to be appeared on the screen */
|
||||
int row,col; /* to store the number of rows and *
|
||||
* the number of colums of the screen */
|
||||
initscr(); /* start the curses mode */
|
||||
getmaxyx(stdscr,row,col); /* get the number of rows and columns */
|
||||
mvprintw(row/2,(col-strlen(mesg))/2,"%s",mesg);
|
||||
/* print the message at the center of the screen */
|
||||
mvprintw(row-2,0,"This screen has %d rows and %d columns\n",row,col);
|
||||
printw("Try resizing your window(if possible) and then run this program again");
|
||||
refresh();
|
||||
getch();
|
||||
endwin();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#include <ncurses.h> /* ncurses.h includes stdio.h */
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char mesg[]="Enter a string: "; /* message to be appeared on the screen */
|
||||
char str[80];
|
||||
int row,col; /* to store the number of rows and *
|
||||
* the number of colums of the screen */
|
||||
initscr(); /* start the curses mode */
|
||||
getmaxyx(stdscr,row,col); /* get the number of rows and columns */
|
||||
mvprintw(row/2,(col-strlen(mesg))/2,"%s",mesg);
|
||||
/* print the message at the center of the screen */
|
||||
getstr(str);
|
||||
mvprintw(LINES - 2, 0, "You Entered: %s", str);
|
||||
getch();
|
||||
endwin();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ch, prev;
|
||||
FILE *fp;
|
||||
int goto_prev = FALSE, y, x;
|
||||
|
||||
if(argc != 2)
|
||||
{ printf("Usage: %s <a c file name>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
fp = fopen(argv[1], "r");
|
||||
if(fp == NULL)
|
||||
{ perror("Cannot open input file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
initscr(); /* Start curses mode */
|
||||
|
||||
prev = EOF;
|
||||
while((ch = fgetc(fp)) != EOF)
|
||||
{ if(prev == '/' && ch == '*') /* If it is / and * then olny
|
||||
* switch bold on */
|
||||
{ attron(A_BOLD);
|
||||
goto_prev = TRUE; /* Go to previous char / and
|
||||
* print it in BOLD */
|
||||
}
|
||||
if(goto_prev == TRUE)
|
||||
{ getyx(stdscr, y, x);
|
||||
move(y, x - 1);
|
||||
printw("%c%c", '/', ch); /* The actual printing is done
|
||||
* here */
|
||||
ch = 'a'; /* 'a' is just a dummy
|
||||
* character to prevent */
|
||||
// "/*/" comments.
|
||||
goto_prev = FALSE; /* Set it to FALSE or every
|
||||
* thing from here will be / */
|
||||
} else
|
||||
printw("%c", ch);
|
||||
refresh();
|
||||
if(prev == '*' && ch == '/')
|
||||
attroff(A_BOLD); /* Switch it off once we got *
|
||||
and then / */
|
||||
prev = ch;
|
||||
}
|
||||
getch();
|
||||
endwin(); /* End curses mode */
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string);
|
||||
int main(int argc, char *argv[])
|
||||
{ initscr(); /* Start curses mode */
|
||||
if(has_colors() == FALSE)
|
||||
{ endwin();
|
||||
printf("You terminal does not support color\n");
|
||||
exit(1);
|
||||
}
|
||||
start_color(); /* Start color */
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
|
||||
attron(COLOR_PAIR(1));
|
||||
print_in_middle(stdscr, LINES / 2, 0, 0, "Viola !!! In color ...");
|
||||
attroff(COLOR_PAIR(1));
|
||||
getch();
|
||||
endwin();
|
||||
}
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
refresh();
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#include <stdio.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
#define WIDTH 30
|
||||
#define HEIGHT 10
|
||||
|
||||
int startx = 0;
|
||||
int starty = 0;
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Exit",
|
||||
};
|
||||
int n_choices = sizeof(choices) / sizeof(char *);
|
||||
void print_menu(WINDOW *menu_win, int highlight);
|
||||
|
||||
int main()
|
||||
{ WINDOW *menu_win;
|
||||
int highlight = 1;
|
||||
int choice = 0;
|
||||
int c;
|
||||
|
||||
initscr();
|
||||
clear();
|
||||
noecho();
|
||||
cbreak(); /* Line buffering disabled. pass on everything */
|
||||
startx = (80 - WIDTH) / 2;
|
||||
starty = (24 - HEIGHT) / 2;
|
||||
|
||||
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
|
||||
keypad(menu_win, TRUE);
|
||||
mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice");
|
||||
refresh();
|
||||
print_menu(menu_win, highlight);
|
||||
while(1)
|
||||
{ c = wgetch(menu_win);
|
||||
switch(c)
|
||||
{ case KEY_UP:
|
||||
if(highlight == 1)
|
||||
highlight = n_choices;
|
||||
else
|
||||
--highlight;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if(highlight == n_choices)
|
||||
highlight = 1;
|
||||
else
|
||||
++highlight;
|
||||
break;
|
||||
case 10:
|
||||
choice = highlight;
|
||||
break;
|
||||
default:
|
||||
mvprintw(24, 0, "Charcter pressed is = %3d Hopefully it can be printed as '%c'", c, c);
|
||||
refresh();
|
||||
break;
|
||||
}
|
||||
print_menu(menu_win, highlight);
|
||||
if(choice != 0) /* User did a choice come out of the infinite loop */
|
||||
break;
|
||||
}
|
||||
mvprintw(23, 0, "You chose choice %d with choice string %s\n", choice, choices[choice - 1]);
|
||||
clrtoeol();
|
||||
refresh();
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_menu(WINDOW *menu_win, int highlight)
|
||||
{
|
||||
int x, y, i;
|
||||
|
||||
x = 2;
|
||||
y = 2;
|
||||
box(menu_win, 0, 0);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
{ if(highlight == i + 1) /* High light the present choice */
|
||||
{ wattron(menu_win, A_REVERSE);
|
||||
mvwprintw(menu_win, y, x, "%s", choices[i]);
|
||||
wattroff(menu_win, A_REVERSE);
|
||||
}
|
||||
else
|
||||
mvwprintw(menu_win, y, x, "%s", choices[i]);
|
||||
++y;
|
||||
}
|
||||
wrefresh(menu_win);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
initscr(); /* Start curses mode */
|
||||
printw("Hello World !!!\n"); /* Print Hello World */
|
||||
refresh(); /* Print it on to the real screen */
|
||||
def_prog_mode(); /* Save the tty modes */
|
||||
endwin(); /* End curses mode temporarily */
|
||||
system("/bin/sh"); /* Do whatever you like in cooked mode */
|
||||
reset_prog_mode(); /* Return to the previous tty mode*/
|
||||
/* stored by def_prog_mode() */
|
||||
refresh(); /* Do refresh() to restore the */
|
||||
/* Screen contents */
|
||||
printw("Another String\n"); /* Back to curses use the full */
|
||||
refresh(); /* capabilities of curses */
|
||||
endwin(); /* End curses mode */
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
|
||||
WINDOW *create_newwin(int height, int width, int starty, int startx);
|
||||
void destroy_win(WINDOW *local_win);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ WINDOW *my_win;
|
||||
int startx, starty, width, height;
|
||||
int ch;
|
||||
|
||||
initscr(); /* Start curses mode */
|
||||
cbreak(); /* Line buffering disabled, Pass on
|
||||
* everty thing to me */
|
||||
keypad(stdscr, TRUE); /* I need that nifty F1 */
|
||||
|
||||
height = 3;
|
||||
width = 10;
|
||||
starty = (LINES - height) / 2; /* Calculating for a center placement */
|
||||
startx = (COLS - width) / 2; /* of the window */
|
||||
printw("Press F1 to exit");
|
||||
refresh();
|
||||
my_win = create_newwin(height, width, starty, startx);
|
||||
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_LEFT:
|
||||
destroy_win(my_win);
|
||||
my_win = create_newwin(height, width, starty,--startx);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
destroy_win(my_win);
|
||||
my_win = create_newwin(height, width, starty,++startx);
|
||||
break;
|
||||
case KEY_UP:
|
||||
destroy_win(my_win);
|
||||
my_win = create_newwin(height, width, --starty,startx);
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
destroy_win(my_win);
|
||||
my_win = create_newwin(height, width, ++starty,startx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
endwin(); /* End curses mode */
|
||||
return 0;
|
||||
}
|
||||
|
||||
WINDOW *create_newwin(int height, int width, int starty, int startx)
|
||||
{ WINDOW *local_win;
|
||||
|
||||
local_win = newwin(height, width, starty, startx);
|
||||
box(local_win, 0 , 0); /* 0, 0 gives default characters
|
||||
* for the vertical and horizontal
|
||||
* lines */
|
||||
wrefresh(local_win); /* Show that box */
|
||||
|
||||
return local_win;
|
||||
}
|
||||
|
||||
void destroy_win(WINDOW *local_win)
|
||||
{
|
||||
/* box(local_win, ' ', ' '); : This won't produce the desired
|
||||
* result of erasing the window. It will leave it's four corners
|
||||
* and so an ugly remnant of window.
|
||||
*/
|
||||
wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' ');
|
||||
/* The parameters taken are
|
||||
* 1. win: the window on which to operate
|
||||
* 2. ls: character to be used for the left side of the window
|
||||
* 3. rs: character to be used for the right side of the window
|
||||
* 4. ts: character to be used for the top side of the window
|
||||
* 5. bs: character to be used for the bottom side of the window
|
||||
* 6. tl: character to be used for the top left corner of the window
|
||||
* 7. tr: character to be used for the top right corner of the window
|
||||
* 8. bl: character to be used for the bottom left corner of the window
|
||||
* 9. br: character to be used for the bottom right corner of the window
|
||||
*/
|
||||
wrefresh(local_win);
|
||||
delwin(local_win);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#include <ncurses.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{ initscr(); /* Start curses mode */
|
||||
start_color(); /* Start color functionality */
|
||||
|
||||
init_pair(1, COLOR_CYAN, COLOR_BLACK);
|
||||
printw("A Big string which i didn't care to type fully ");
|
||||
mvchgat(0, 0, -1, A_BLINK, 1, NULL);
|
||||
/*
|
||||
* First two parameters specify the position at which to start
|
||||
* Third parameter number of characters to update. -1 means till
|
||||
* end of line
|
||||
* Forth parameter is the normal attribute you wanted to give
|
||||
* to the charcter
|
||||
* Fifth is the color index. It is the index given during init_pair()
|
||||
* use 0 if you didn't want color
|
||||
* Sixth one is always NULL
|
||||
*/
|
||||
refresh();
|
||||
getch();
|
||||
endwin(); /* End curses mode */
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
# Makefile for JustForFun Files
|
||||
|
||||
# A few variables
|
||||
|
||||
CC=gcc
|
||||
LIBS=-lform -lncurses
|
||||
|
||||
SRC_DIR=.
|
||||
EXE_DIR=../demo/exe
|
||||
|
||||
EXES = \
|
||||
${EXE_DIR}/form_attrib\
|
||||
${EXE_DIR}/form_options\
|
||||
${EXE_DIR}/form_simple\
|
||||
${EXE_DIR}/form_win \
|
||||
|
||||
${EXE_DIR}/%: %.o
|
||||
${CC} -o $@ $< ${LIBS}
|
||||
|
||||
%.o: ${SRC_DIR}/%.c
|
||||
${CC} -o $@ -c $<
|
||||
|
||||
all: ${EXES}
|
||||
|
||||
|
||||
clean:
|
||||
@rm -f ${EXES}
|
|
@ -0,0 +1,9 @@
|
|||
Description of files
|
||||
--------------------
|
||||
forms
|
||||
|
|
||||
|----> form_attrib.c -- Usage of field attributes
|
||||
|----> form_options.c -- Usage of field options
|
||||
|----> form_simple.c -- A simple form example
|
||||
|----> form_win.c -- Demo of windows associated with forms
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#include <form.h>
|
||||
|
||||
int main()
|
||||
{ FIELD *field[3];
|
||||
FORM *my_form;
|
||||
int ch;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize few color pairs */
|
||||
init_pair(1, COLOR_WHITE, COLOR_BLUE);
|
||||
init_pair(2, COLOR_WHITE, COLOR_BLUE);
|
||||
|
||||
/* Initialize the fields */
|
||||
field[0] = new_field(1, 10, 4, 18, 0, 0);
|
||||
field[1] = new_field(1, 10, 6, 18, 0, 0);
|
||||
field[2] = NULL;
|
||||
|
||||
/* Set field options */
|
||||
set_field_fore(field[0], COLOR_PAIR(1));/* Put the field with blue background */
|
||||
set_field_back(field[0], COLOR_PAIR(2));/* and white foreground (characters */
|
||||
/* are printed in white */
|
||||
field_opts_off(field[0], O_AUTOSKIP); /* Don't go to next field when this */
|
||||
/* Field is filled up */
|
||||
set_field_back(field[1], A_UNDERLINE);
|
||||
field_opts_off(field[1], O_AUTOSKIP);
|
||||
|
||||
/* Create the form and post it */
|
||||
my_form = new_form(field);
|
||||
post_form(my_form);
|
||||
refresh();
|
||||
|
||||
set_current_field(my_form, field[0]); /* Set focus to the colored field */
|
||||
mvprintw(4, 10, "Value 1:");
|
||||
mvprintw(6, 10, "Value 2:");
|
||||
mvprintw(LINES - 2, 0, "Use UP, DOWN arrow keys to switch between fields");
|
||||
refresh();
|
||||
|
||||
/* Loop through to get user requests */
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_DOWN:
|
||||
/* Go to next field */
|
||||
form_driver(my_form, REQ_NEXT_FIELD);
|
||||
/* Go to the end of the present buffer */
|
||||
/* Leaves nicely at the last character */
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
case KEY_UP:
|
||||
/* Go to previous field */
|
||||
form_driver(my_form, REQ_PREV_FIELD);
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
default:
|
||||
/* If this is a normal character, it gets */
|
||||
/* Printed */
|
||||
form_driver(my_form, ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Un post form and free the memory */
|
||||
unpost_form(my_form);
|
||||
free_form(my_form);
|
||||
free_field(field[0]);
|
||||
free_field(field[1]);
|
||||
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
#include <form.h>
|
||||
|
||||
#define STARTX 15
|
||||
#define STARTY 4
|
||||
#define WIDTH 25
|
||||
|
||||
#define N_FIELDS 3
|
||||
|
||||
int main()
|
||||
{ FIELD *field[N_FIELDS];
|
||||
FORM *my_form;
|
||||
int ch, i;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize the fields */
|
||||
for(i = 0; i < N_FIELDS - 1; ++i)
|
||||
field[i] = new_field(1, WIDTH, STARTY + i * 2, STARTX, 0, 0);
|
||||
field[N_FIELDS - 1] = NULL;
|
||||
|
||||
/* Set field options */
|
||||
set_field_back(field[1], A_UNDERLINE); /* Print a line for the option */
|
||||
|
||||
field_opts_off(field[0], O_ACTIVE); /* This field is a static label */
|
||||
field_opts_off(field[1], O_PUBLIC); /* This filed is like a password field*/
|
||||
field_opts_off(field[1], O_AUTOSKIP); /* To avoid entering the same field */
|
||||
/* after last character is entered */
|
||||
|
||||
/* Create the form and post it */
|
||||
my_form = new_form(field);
|
||||
post_form(my_form);
|
||||
refresh();
|
||||
|
||||
set_field_just(field[0], JUSTIFY_CENTER); /* Center Justification */
|
||||
set_field_buffer(field[0], 0, "This is a static Field");
|
||||
/* Initialize the field */
|
||||
mvprintw(STARTY, STARTX - 10, "Field 1:");
|
||||
mvprintw(STARTY + 2, STARTX - 10, "Field 2:");
|
||||
refresh();
|
||||
|
||||
/* Loop through to get user requests */
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_DOWN:
|
||||
/* Go to next field */
|
||||
form_driver(my_form, REQ_NEXT_FIELD);
|
||||
/* Go to the end of the present buffer */
|
||||
/* Leaves nicely at the last character */
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
case KEY_UP:
|
||||
/* Go to previous field */
|
||||
form_driver(my_form, REQ_PREV_FIELD);
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
default:
|
||||
/* If this is a normal character, it gets */
|
||||
/* Printed */
|
||||
form_driver(my_form, ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Un post form and free the memory */
|
||||
unpost_form(my_form);
|
||||
free_form(my_form);
|
||||
free_field(field[0]);
|
||||
free_field(field[1]);
|
||||
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#include <form.h>
|
||||
|
||||
int main()
|
||||
{ FIELD *field[3];
|
||||
FORM *my_form;
|
||||
int ch;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize the fields */
|
||||
field[0] = new_field(1, 10, 4, 18, 0, 0);
|
||||
field[1] = new_field(1, 10, 6, 18, 0, 0);
|
||||
field[2] = NULL;
|
||||
|
||||
/* Set field options */
|
||||
set_field_back(field[0], A_UNDERLINE); /* Print a line for the option */
|
||||
field_opts_off(field[0], O_AUTOSKIP); /* Don't go to next field when this */
|
||||
/* Field is filled up */
|
||||
set_field_back(field[1], A_UNDERLINE);
|
||||
field_opts_off(field[1], O_AUTOSKIP);
|
||||
|
||||
/* Create the form and post it */
|
||||
my_form = new_form(field);
|
||||
post_form(my_form);
|
||||
refresh();
|
||||
|
||||
mvprintw(4, 10, "Value 1:");
|
||||
mvprintw(6, 10, "Value 2:");
|
||||
refresh();
|
||||
|
||||
/* Loop through to get user requests */
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_DOWN:
|
||||
/* Go to next field */
|
||||
form_driver(my_form, REQ_NEXT_FIELD);
|
||||
/* Go to the end of the present buffer */
|
||||
/* Leaves nicely at the last character */
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
case KEY_UP:
|
||||
/* Go to previous field */
|
||||
form_driver(my_form, REQ_PREV_FIELD);
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
default:
|
||||
/* If this is a normal character, it gets */
|
||||
/* Printed */
|
||||
form_driver(my_form, ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Un post form and free the memory */
|
||||
unpost_form(my_form);
|
||||
free_form(my_form);
|
||||
free_field(field[0]);
|
||||
free_field(field[1]);
|
||||
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
#include <form.h>
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
|
||||
|
||||
int main()
|
||||
{
|
||||
FIELD *field[3];
|
||||
FORM *my_form;
|
||||
WINDOW *my_form_win;
|
||||
int ch, rows, cols;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize few color pairs */
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
|
||||
/* Initialize the fields */
|
||||
field[0] = new_field(1, 10, 6, 1, 0, 0);
|
||||
field[1] = new_field(1, 10, 8, 1, 0, 0);
|
||||
field[2] = NULL;
|
||||
|
||||
/* Set field options */
|
||||
set_field_back(field[0], A_UNDERLINE);
|
||||
field_opts_off(field[0], O_AUTOSKIP); /* Don't go to next field when this */
|
||||
/* Field is filled up */
|
||||
set_field_back(field[1], A_UNDERLINE);
|
||||
field_opts_off(field[1], O_AUTOSKIP);
|
||||
|
||||
/* Create the form and post it */
|
||||
my_form = new_form(field);
|
||||
|
||||
/* Calculate the area required for the form */
|
||||
scale_form(my_form, &rows, &cols);
|
||||
|
||||
/* Create the window to be associated with the form */
|
||||
my_form_win = newwin(rows + 4, cols + 4, 4, 4);
|
||||
keypad(my_form_win, TRUE);
|
||||
|
||||
/* Set main window and sub window */
|
||||
set_form_win(my_form, my_form_win);
|
||||
set_form_sub(my_form, derwin(my_form_win, rows, cols, 2, 2));
|
||||
|
||||
/* Print a border around the main window and print a title */
|
||||
box(my_form_win, 0, 0);
|
||||
print_in_middle(my_form_win, 1, 0, cols + 4, "My Form", COLOR_PAIR(1));
|
||||
|
||||
post_form(my_form);
|
||||
wrefresh(my_form_win);
|
||||
|
||||
mvprintw(LINES - 2, 0, "Use UP, DOWN arrow keys to switch between fields");
|
||||
refresh();
|
||||
|
||||
/* Loop through to get user requests */
|
||||
while((ch = wgetch(my_form_win)) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case KEY_DOWN:
|
||||
/* Go to next field */
|
||||
form_driver(my_form, REQ_NEXT_FIELD);
|
||||
/* Go to the end of the present buffer */
|
||||
/* Leaves nicely at the last character */
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
case KEY_UP:
|
||||
/* Go to previous field */
|
||||
form_driver(my_form, REQ_PREV_FIELD);
|
||||
form_driver(my_form, REQ_END_LINE);
|
||||
break;
|
||||
default:
|
||||
/* If this is a normal character, it gets */
|
||||
/* Printed */
|
||||
form_driver(my_form, ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Un post form and free the memory */
|
||||
unpost_form(my_form);
|
||||
free_form(my_form);
|
||||
free_field(field[0]);
|
||||
free_field(field[1]);
|
||||
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
wattron(win, color);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
wattroff(win, color);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,902 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
# Front end to the ncurses programs compilation and run
|
||||
# Implemented using 'dialog' which inturn uses ncurses
|
||||
|
||||
|
||||
# Author: N N Ashok (nnashok@yahoo.com)
|
||||
# Date: 07/15/2002
|
||||
#
|
||||
# Modified by: Pradeep Padala (ppadala@cise.ufl.edu)
|
||||
|
||||
# Notes:
|
||||
# Basics:
|
||||
# Makefile does not build acs_vars
|
||||
# Done: hello_world: Nothing displayed to user??
|
||||
# Done: init_func_example: Nothing displayed to user??
|
||||
# Done: key_code: Does not exit with status 0
|
||||
# mouse_menu: Didnot work for me. Had to hit ^C
|
||||
# Done: simple_attr: The output does not stay, is scrolled fast
|
||||
# Done: simple_color: Nothing displayed to user??
|
||||
# temp_leave: When executed using the gui, the tty is not reset. Nothing
|
||||
# echos to the screen
|
||||
# Done: with_chgat: Nothing displayed to user??
|
||||
# with_chgat: Does not indicate how to exit
|
||||
#
|
||||
# Forms:
|
||||
# None of the programs indicate how to exit. F1 exits the program.
|
||||
# Menus:
|
||||
# menu_simple does not indicate how to exit. F1 exits the program.
|
||||
# menu_win does not indicate how to exit. F1 exits the program.
|
||||
# Panels:
|
||||
# panel_resize: It seg faulted when I was resizing. Probably
|
||||
# the size had gone to negative value (I cant see the size being reduced,
|
||||
# only after I press the Enter do I see the new size).
|
||||
# panel_simple: Exists as soon as I press any key.
|
||||
|
||||
# Modified source files:
|
||||
# basics/hello_world.c
|
||||
# basics/init_func_example.c
|
||||
# basics/key_code.c
|
||||
# basics/simple_attr.c
|
||||
# basics/simple_color.c
|
||||
# basics/with_chgat.c
|
||||
|
||||
|
||||
|
||||
# Constants used
|
||||
TRUE=0;
|
||||
FALSE=-1;
|
||||
EXEC_DIR="../demo/exe";
|
||||
TEMP_FILE="/tmp/make.out";
|
||||
tmp="tmp.out"
|
||||
|
||||
|
||||
# Function declarations
|
||||
|
||||
# execMake: Function to execute 'make'
|
||||
# Arguments:
|
||||
# clean: Spcifies to do a 'make clean'
|
||||
execMake()
|
||||
{
|
||||
local clean;
|
||||
local result;
|
||||
|
||||
# Check for arguments
|
||||
if [ "$1" == "clean" ]
|
||||
then
|
||||
clean="clean";
|
||||
else
|
||||
clean="";
|
||||
fi
|
||||
|
||||
make $clean > $TEMP_FILE 2>&1
|
||||
result=$?;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
# source_menu: Function to display the source code menu
|
||||
# Arguments: None
|
||||
source_menu()
|
||||
{
|
||||
|
||||
local menu_items;
|
||||
|
||||
files_c=`ls *.c`;
|
||||
files=`echo $files_c | sed -e 's/\.c//g'`;
|
||||
|
||||
title="Source code";
|
||||
|
||||
command_options="";
|
||||
# Set to 1 to include the "Previous" entry and an extra space at the end
|
||||
menu_items=2;
|
||||
for i in $files
|
||||
do
|
||||
command_options="$command_options $i $i.c";
|
||||
menu_items=`expr $menu_items + 1`;
|
||||
done;
|
||||
|
||||
if [ $menu_items -gt 13 ]
|
||||
then
|
||||
menu_items=13;
|
||||
fi
|
||||
|
||||
# While the user selects some menu option, repeat
|
||||
statusSource=0;
|
||||
while (test "$statusSource" = "0")
|
||||
do
|
||||
dialog --clear --menu "$title" 20 60 $menu_items $command_options Previous "Return to previous screen" 2>$tmp
|
||||
resultSource=`cat $tmp`;
|
||||
statusSource=`echo $?`;
|
||||
|
||||
# None of the programs need additional arguments and all exit
|
||||
# normally (^C not required to exit)
|
||||
if [ $statusSource -eq 0 ]
|
||||
then
|
||||
if [ "$resultSource" == "Previous" ]
|
||||
then
|
||||
statusSource=1;
|
||||
else
|
||||
if [ -n "$EDITOR" ]
|
||||
then
|
||||
$EDITOR $resultSource.c;
|
||||
else
|
||||
dialog --clear --msgbox "EDITOR environment variable is not set. Please set it to your favorite editor and rerun the program." 10 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# runBasics: Function to run the programs in the Basics category
|
||||
# Arguments: None
|
||||
runBasics()
|
||||
{
|
||||
local cwd;
|
||||
local progs_array;
|
||||
local title;
|
||||
local count;
|
||||
local command_options;
|
||||
local statusRunBasics;
|
||||
local resultRunBasics;
|
||||
local string_args;
|
||||
|
||||
|
||||
# Programs to run
|
||||
progs_array[1]="acs_vars";
|
||||
progs_array[2]="hello_world";
|
||||
progs_array[3]="init_func_example";
|
||||
progs_array[4]="key_code";
|
||||
progs_array[5]="mouse_menu";
|
||||
progs_array[6]="other_border";
|
||||
progs_array[7]="printw_example";
|
||||
progs_array[8]="scanw_example";
|
||||
progs_array[9]="simple_attr";
|
||||
progs_array[10]="simple_color";
|
||||
progs_array[11]="simple_key";
|
||||
progs_array[12]="temp_leave";
|
||||
progs_array[13]="win_border";
|
||||
progs_array[14]="with_chgat";
|
||||
|
||||
|
||||
# Save current directory
|
||||
cwd=`pwd`;
|
||||
|
||||
cd $EXEC_DIR;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $EXEC_DIR" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
title="Basics";
|
||||
|
||||
# Number of programs
|
||||
count=14;
|
||||
command_options="";
|
||||
while [ $count -gt 0 ]
|
||||
do
|
||||
command_options="$command_options ${progs_array[$count]} ${progs_array[$count]}";
|
||||
count=`expr $count - 1`;
|
||||
done
|
||||
|
||||
|
||||
# While the user selects some menu option, repeat
|
||||
statusRunBasics=0;
|
||||
while (test "$statusRunBasics" = "0")
|
||||
do
|
||||
dialog --clear --menu "$title" 20 60 12 $command_options Previous "Return to previous screen" 2>$tmp
|
||||
resultRunBasics=`cat $tmp`;
|
||||
statusRunBasics=`echo $?`;
|
||||
|
||||
# None of the programs except "simple_attr" need additional
|
||||
# arguments and all exit normally (^C not required to exit)
|
||||
if [ $statusRunBasics -eq 0 ]
|
||||
then
|
||||
if [ "$resultRunBasics" == "Previous" ]
|
||||
then
|
||||
statusRunBasics=1;
|
||||
elif [ "$resultRunBasics" == "simple_attr" ]
|
||||
then
|
||||
dialog --clear --inputbox "Enter the name of a C file (pwd: demo/exe)" 10 60 2>$tmp
|
||||
string_arg=`cat $tmp`;
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
./$resultRunBasics $string_arg 2>$TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './$resultRunBasics'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
else
|
||||
./$resultRunBasics 2> $TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './$resultRunBasics'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd $cwd;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $cwd" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
# runForms: Function to run the programs in the Forms category
|
||||
# Arguments: None
|
||||
runForms()
|
||||
{
|
||||
local cwd;
|
||||
local progs_array;
|
||||
local title;
|
||||
local count;
|
||||
local command_options;
|
||||
local statusRunForms;
|
||||
local resultRunForms;
|
||||
|
||||
|
||||
|
||||
# Programs to run
|
||||
progs_array[1]="form_attrib";
|
||||
progs_array[2]="form_options";
|
||||
progs_array[3]="form_simple";
|
||||
progs_array[4]="form_win";
|
||||
|
||||
|
||||
# Save current directory
|
||||
cwd=`pwd`;
|
||||
|
||||
cd $EXEC_DIR;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $EXEC_DIR" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
title="Forms";
|
||||
|
||||
# Number of programs
|
||||
count=4;
|
||||
command_options="";
|
||||
while [ $count -gt 0 ]
|
||||
do
|
||||
command_options="$command_options ${progs_array[$count]} ${progs_array[$count]}";
|
||||
count=`expr $count - 1`;
|
||||
done
|
||||
|
||||
|
||||
# While the user selects some menu option, repeat
|
||||
statusRunForms=0;
|
||||
while (test "$statusRunForms" = "0")
|
||||
do
|
||||
dialog --clear --menu "$title" 20 60 7 $command_options Previous "Return to previous screen" 2>$tmp
|
||||
resultRunForms=`cat $tmp`;
|
||||
statusRunForms=`echo $?`;
|
||||
|
||||
# None of the programs need additional arguments and all exit
|
||||
# normally (^C not required to exit)
|
||||
if [ $statusRunForms -eq 0 ]
|
||||
then
|
||||
if [ "$resultRunForms" == "Previous" ]
|
||||
then
|
||||
statusRunForms=1;
|
||||
else
|
||||
./$resultRunForms 2> $TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './$resultRunForms'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd $cwd;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $cwd" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
# runMenus: Function to run the programs in the Menus category
|
||||
# Arguments: None
|
||||
runMenus()
|
||||
{
|
||||
local cwd;
|
||||
local progs_array;
|
||||
local title;
|
||||
local count;
|
||||
local command_options;
|
||||
local statusRunMenus;
|
||||
local resultRunMenus;
|
||||
|
||||
|
||||
|
||||
# Programs to run
|
||||
progs_array[1]="menu_attrib";
|
||||
progs_array[2]="menu_item_data";
|
||||
progs_array[3]="menu_multi_column";
|
||||
progs_array[4]="menu_scroll";
|
||||
progs_array[5]="menu_simple";
|
||||
progs_array[6]="menu_toggle";
|
||||
progs_array[7]="menu_userptr";
|
||||
progs_array[8]="menu_win";
|
||||
|
||||
|
||||
# Save current directory
|
||||
cwd=`pwd`;
|
||||
|
||||
cd $EXEC_DIR;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $EXEC_DIR" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
title="Menus";
|
||||
|
||||
# Number of programs
|
||||
count=8;
|
||||
command_options="";
|
||||
while [ $count -gt 0 ]
|
||||
do
|
||||
command_options="$command_options ${progs_array[$count]} ${progs_array[$count]}";
|
||||
count=`expr $count - 1`;
|
||||
done
|
||||
|
||||
|
||||
# While the user selects some menu option, repeat
|
||||
statusRunMenus=0;
|
||||
while (test "$statusRunMenus" = "0")
|
||||
do
|
||||
dialog --clear --menu "$title" 20 60 10 $command_options Previous "Return to previous screen" 2>$tmp
|
||||
resultRunMenus=`cat $tmp`;
|
||||
statusRunMenus=`echo $?`;
|
||||
|
||||
# None of the programs need additional arguments and all exit
|
||||
# normally (^C not required to exit)
|
||||
if [ $statusRunMenus -eq 0 ]
|
||||
then
|
||||
if [ "$resultRunMenus" == "Previous" ]
|
||||
then
|
||||
statusRunMenus=1;
|
||||
else
|
||||
./$resultRunMenus 2> $TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './$resultRunMenus'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd $cwd;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $cwd" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
# runPanels: Function to run the programs in the Panels category
|
||||
# Arguments: None
|
||||
runPanels()
|
||||
{
|
||||
local cwd;
|
||||
local progs_array;
|
||||
local title;
|
||||
local count;
|
||||
local command_options;
|
||||
local statusRunPanels;
|
||||
local resultRunPanels;
|
||||
|
||||
|
||||
|
||||
# Programs to run
|
||||
progs_array[1]="panel_browse";
|
||||
progs_array[2]="panel_hide";
|
||||
progs_array[3]="panel_resize";
|
||||
progs_array[4]="panel_simple";
|
||||
|
||||
|
||||
# Save current directory
|
||||
cwd=`pwd`;
|
||||
|
||||
cd $EXEC_DIR;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $EXEC_DIR" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
title="Panels";
|
||||
|
||||
# Number of programs
|
||||
count=8;
|
||||
command_options="";
|
||||
while [ $count -gt 0 ]
|
||||
do
|
||||
command_options="$command_options ${progs_array[$count]} ${progs_array[$count]}";
|
||||
count=`expr $count - 1`;
|
||||
done
|
||||
|
||||
|
||||
# While the user selects some menu option, repeat
|
||||
statusRunPanels=0;
|
||||
while (test "$statusRunPanels" = "0")
|
||||
do
|
||||
dialog --clear --menu "$title" 20 60 7 $command_options Previous "Return to previous screen" 2>$tmp
|
||||
resultRunPanels=`cat $tmp`;
|
||||
statusRunPanels=`echo $?`;
|
||||
|
||||
# None of the programs need additional arguments and all exit
|
||||
# normally (^C not required to exit)
|
||||
if [ $statusRunPanels -eq 0 ]
|
||||
then
|
||||
if [ "$resultRunPanels" == "Previous" ]
|
||||
then
|
||||
statusRunPanels=1;
|
||||
else
|
||||
./$resultRunPanels 2> $TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './$resultRunPanels'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd $cwd;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $cwd" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
# runJustForFun: Function to run the programs in the JustForFun category
|
||||
# Arguments: None
|
||||
runJustForFun()
|
||||
{
|
||||
local cwd;
|
||||
local progs_array;
|
||||
local title;
|
||||
local count;
|
||||
local command_options;
|
||||
local statusRunJustForFun;
|
||||
local resultRunJustForFun;
|
||||
local num_arg;
|
||||
|
||||
|
||||
|
||||
# Programs to run
|
||||
progs_array[1]="hanoi";
|
||||
progs_array[2]="life";
|
||||
progs_array[3]="magic";
|
||||
progs_array[4]="queens";
|
||||
progs_array[5]="shuffle";
|
||||
progs_array[6]="tt";
|
||||
|
||||
|
||||
# Save current directory
|
||||
cwd=`pwd`;
|
||||
|
||||
cd $EXEC_DIR;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $EXEC_DIR" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
title="Just For Fun";
|
||||
|
||||
# Number of programs
|
||||
count=6;
|
||||
command_options="";
|
||||
while [ $count -gt 0 ]
|
||||
do
|
||||
command_options="$command_options ${progs_array[$count]} ${progs_array[$count]}";
|
||||
count=`expr $count - 1`;
|
||||
done
|
||||
|
||||
|
||||
# While the user selects some menu option, repeat
|
||||
statusRunJustForFun=0;
|
||||
while (test "$statusRunJustForFun" = "0")
|
||||
do
|
||||
resultRunJustForFun=`dialog --clear --menu "$title" 20 60 10 $command_options Previous "Return to previous screen" 2>&1`;
|
||||
statusRunJustForFun=`echo $?`;
|
||||
|
||||
case "$resultRunJustForFun" in
|
||||
"hanoi")
|
||||
./hanoi 2> $TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './hanoi'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
|
||||
;;
|
||||
"life")
|
||||
./life 2> $TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './hanoi'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
|
||||
;;
|
||||
"magic")
|
||||
num_arg=`dialog --clear --inputbox "Enter the size of the magic square" 10 40 2>&1`;
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# Check if an integer
|
||||
echo $num_arg | grep -E -e [^0-9];
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
./magic $num_arg 2>$TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './magic'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
;;
|
||||
"queens")
|
||||
num_arg=`dialog --clear --inputbox "Enter the number of qeens (chess board order) ( > 3)" 10 40 2>&1`;
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# Check if an integer
|
||||
echo $num_arg | grep -E -e [^0-9];
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
./queens $num_arg 2>$TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './queens'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
;;
|
||||
"shuffle")
|
||||
num_arg=`dialog --clear --inputbox "Enter the order of the shuffle board" 10 40 2>&1`;
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
# Check if an integer
|
||||
echo $num_arg | grep -E -e [^0-9];
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
./shuffle $num_arg 2>$TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './shuffle'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
;;
|
||||
"tt")
|
||||
./tt 2>$TEMP_FILE;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
if [ `wc -c $TEMP_FILE | awk {'print \$1'}` -ne 0 ]
|
||||
then
|
||||
echo "
|
||||
Unable to run './tt'" >> $TEMP_FILE;
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
Previous)
|
||||
statusRunJustForFun="1";
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
cd $cwd;
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
dialog --clear --msgbox "Unable to change to $cwd" 5 40;
|
||||
return $FALSE;
|
||||
fi
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# submenu: Generic function to process submenus (display submenu for a
|
||||
# category
|
||||
# Arguments: Title, run_function
|
||||
# run_function: This function is invoked when the 'Run' item is choosen
|
||||
submenu()
|
||||
{
|
||||
local cwdSubmenu;
|
||||
local statusSubmenu;
|
||||
local title
|
||||
local resultSubmenu;
|
||||
|
||||
# Save current working directory
|
||||
cwdSubmenu=`pwd`;
|
||||
|
||||
#While the user selects some menu option, repeat
|
||||
statusSubmenu=0
|
||||
title="$1";
|
||||
while (test "$statusSubmenu" = "0")
|
||||
do
|
||||
# Create the main menu dialog box
|
||||
dialog --clear --menu "NCURSES Programming HOWTO $title Sample Programs" 20 60 8 Make "Make programs" Clean "Clean programs" Run "Run programs" Source "View source code for programs" readme "View the readme file" makefile "View the Makefile" Previous "Return to previous screen" 2>$tmp
|
||||
resultSubmenu=`cat $tmp`
|
||||
statusSubmenu=`echo $?`
|
||||
case $resultSubmenu in
|
||||
Make)
|
||||
execMake
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "
|
||||
'make' successful" >> $TEMP_FILE;
|
||||
else
|
||||
echo "
|
||||
Unable to run 'make'" >> $TEMP_FILE;
|
||||
fi
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
|
||||
;;
|
||||
Clean)
|
||||
execMake "clean";
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "
|
||||
'make clean' successful" >> $TEMP_FILE;
|
||||
else
|
||||
echo "
|
||||
Unable to run 'make clean'" >> $TEMP_FILE;
|
||||
fi
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
|
||||
;;
|
||||
Run)
|
||||
# Run the programs: The function name passed
|
||||
# to this function as $2
|
||||
$2;
|
||||
|
||||
;;
|
||||
Source)
|
||||
# Bring up the source code menu
|
||||
source_menu;
|
||||
|
||||
;;
|
||||
readme)
|
||||
if [ -n "$EDITOR" ]
|
||||
then
|
||||
$EDITOR README;
|
||||
else
|
||||
dialog --clear --msgbox "EDITOR environment variable is not set. Please set it to your favorite editor and rerun the program." 10 40;
|
||||
fi
|
||||
|
||||
;;
|
||||
makefile)
|
||||
if [ -n "$EDITOR" ]
|
||||
then
|
||||
$EDITOR Makefile;
|
||||
else
|
||||
dialog --clear --msgbox "EDITOR environment variable is not set. Please set it to your favorite editor and rerun the program." 10 40;
|
||||
fi
|
||||
|
||||
;;
|
||||
Previous)
|
||||
statusSubmenu="1";
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
return $TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# Code starts
|
||||
|
||||
# Initialize the variables
|
||||
basics="basics";
|
||||
forms="forms";
|
||||
menus="menus";
|
||||
panels="panels";
|
||||
JustForFun="JustForFun";
|
||||
|
||||
# Save the current working directory
|
||||
cwd=`pwd`;
|
||||
|
||||
|
||||
#While the user selects some menu option, repeat
|
||||
status=0
|
||||
while (test "$status" = "0")
|
||||
do
|
||||
#Create the main menu dialog box
|
||||
dialog --clear --menu "NCURSES Programming HOWTO Sample Programs" 20 60 10 basics "Basics" forms "Forms" menus "Menus" panels "Panels" JustForFun "Just For Fun" makeall "Make all programs" cleanall "Make clean all programs" readme "View the readme file" makefile "View the Makefile" Quit "Quit" 2>$tmp
|
||||
status=`echo $?`
|
||||
result=`cat $tmp`
|
||||
case $result in
|
||||
basics)
|
||||
cd $basics || dialog --clear --msgbox "Unable to change to directory $basics" 5 40;
|
||||
|
||||
# Call the basics function
|
||||
submenu "Basics" runBasics;
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
dialog --clear --msgbox "Error processing basics" 5 40;
|
||||
fi
|
||||
|
||||
# Change back to the earlier working directory
|
||||
cd $cwd;
|
||||
;;
|
||||
forms)
|
||||
cd $forms || dialog --clear --msgbox "Unable to change to directory $forms" 5 40;
|
||||
|
||||
# Call the forms function
|
||||
submenu "Forms" runForms;
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
dialog --clear --msgbox "Error processing forms" 5 40;
|
||||
fi
|
||||
|
||||
# Change back to the earlier working directory
|
||||
cd $cwd;
|
||||
;;
|
||||
menus)
|
||||
cd $menus || dialog --clear --msgbox "Unable to change to directory $menus" 5 40;
|
||||
|
||||
# Call the menus function
|
||||
submenu "Menus" runMenus;
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
dialog --clear --msgbox "Error processing menus" 5 40;
|
||||
fi
|
||||
|
||||
# Change back to the earlier working directory
|
||||
cd $cwd;
|
||||
;;
|
||||
panels)
|
||||
cd $panels || dialog --clear --msgbox "Unable to change to directory $panels" 5 40;
|
||||
|
||||
# Call the menus function
|
||||
submenu "Panels" runPanels;
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
dialog --clear --msgbox "Error processing panels" 5 40;
|
||||
fi
|
||||
|
||||
# Change back to the earlier working directory
|
||||
cd $cwd;
|
||||
;;
|
||||
JustForFun)
|
||||
cd $JustForFun || dialog --clear --msgbox "Unable to change to directory $JustForFun" 5 40;
|
||||
|
||||
# Call the JustForFun function
|
||||
submenu "JustForFun" runJustForFun;
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
dialog --clear --msgbox "Error processing JustForFun" 5 40;
|
||||
fi
|
||||
|
||||
# Change back to the earlier working directory
|
||||
cd $cwd;
|
||||
;;
|
||||
makeall)
|
||||
# Call the execMake function
|
||||
execMake;
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "
|
||||
'make' successful" >> $TEMP_FILE;
|
||||
else
|
||||
echo "
|
||||
Unable to run 'make'" >> $TEMP_FILE;
|
||||
fi
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
|
||||
;;
|
||||
cleanall)
|
||||
# Call the execMake function
|
||||
execMake "clean";
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "
|
||||
'make clean' successful" >> $TEMP_FILE;
|
||||
else
|
||||
echo "
|
||||
Unable to run 'make clean'" >> $TEMP_FILE;
|
||||
fi
|
||||
dialog --clear --textbox $TEMP_FILE 15 60;
|
||||
|
||||
;;
|
||||
readme)
|
||||
if [ -n "$EDITOR" ]
|
||||
then
|
||||
$EDITOR README;
|
||||
else
|
||||
dialog --clear --msgbox "EDITOR environment variable is not set. Please set it to your favorite editor and rerun the program." 10 40;
|
||||
fi
|
||||
|
||||
;;
|
||||
makefile)
|
||||
if [ -n "$EDITOR" ]
|
||||
then
|
||||
$EDITOR Makefile;
|
||||
else
|
||||
dialog --clear --msgbox "EDITOR environment variable is not set. Please set it to your favorite editor and rerun the program." 10 40;
|
||||
fi
|
||||
|
||||
;;
|
||||
Quit)
|
||||
# Remove the TEMP_FILE
|
||||
rm -f $TEMP_FILE;
|
||||
rm -f $tmp;
|
||||
|
||||
status="1";
|
||||
;;
|
||||
esac
|
||||
done
|
|
@ -0,0 +1,31 @@
|
|||
# Makefile for JustForFun Files
|
||||
|
||||
# A few variables
|
||||
|
||||
CC=gcc
|
||||
LIBS=-lmenu -lncurses
|
||||
|
||||
SRC_DIR=.
|
||||
EXE_DIR=../demo/exe
|
||||
|
||||
EXES = \
|
||||
${EXE_DIR}/menu_attrib\
|
||||
${EXE_DIR}/menu_item_data\
|
||||
${EXE_DIR}/menu_multi_column \
|
||||
${EXE_DIR}/menu_scroll \
|
||||
${EXE_DIR}/menu_simple \
|
||||
${EXE_DIR}/menu_toggle \
|
||||
${EXE_DIR}/menu_userptr \
|
||||
${EXE_DIR}/menu_win
|
||||
|
||||
${EXE_DIR}/%: %.o
|
||||
${CC} -o $@ $< ${LIBS}
|
||||
|
||||
%.o: ${SRC_DIR}/%.c
|
||||
${CC} -o $@ -c $<
|
||||
|
||||
all: ${EXES}
|
||||
|
||||
|
||||
clean:
|
||||
@rm -f ${EXES}
|
|
@ -0,0 +1,13 @@
|
|||
Description of files
|
||||
--------------------
|
||||
menus
|
||||
|
|
||||
|----> menu_attrib.c -- Usage of menu attributes
|
||||
|----> menu_item_data.c -- Usage of item_name() etc.. functions
|
||||
|----> menu_multi_column.c -- Creates multi columnar menus
|
||||
|----> menu_scroll.c -- Demonstrates scrolling capability of menus
|
||||
|----> menu_simple.c -- A simple menu accessed by arrow keys
|
||||
|----> menu_toggle.c -- Creates multi valued menus and explains
|
||||
| -- REQ_TOGGLE_ITEM
|
||||
|----> menu_userptr.c -- Usage of user pointer
|
||||
|----> menu_win.c -- Demo of windows associated with menus
|
|
@ -0,0 +1,80 @@
|
|||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Choice 5",
|
||||
"Choice 6",
|
||||
"Choice 7",
|
||||
"Exit",
|
||||
};
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
int n_choices, i;
|
||||
ITEM *cur_item;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(3, COLOR_MAGENTA, COLOR_BLACK);
|
||||
|
||||
/* Initialize items */
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
my_items[n_choices] = (ITEM *)NULL;
|
||||
item_opts_off(my_items[3], O_SELECTABLE);
|
||||
item_opts_off(my_items[6], O_SELECTABLE);
|
||||
|
||||
/* Create menu */
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
|
||||
/* Set fore ground and back ground of the menu */
|
||||
set_menu_fore(my_menu, COLOR_PAIR(1) | A_REVERSE);
|
||||
set_menu_back(my_menu, COLOR_PAIR(2));
|
||||
set_menu_grey(my_menu, COLOR_PAIR(3));
|
||||
|
||||
/* Post the menu */
|
||||
mvprintw(LINES - 3, 0, "Press <ENTER> to see the option selected");
|
||||
mvprintw(LINES - 2, 0, "Up and Down arrow keys to naviage (F1 to Exit)");
|
||||
post_menu(my_menu);
|
||||
refresh();
|
||||
|
||||
while((c = getch()) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case 10: /* Enter */
|
||||
move(20, 0);
|
||||
clrtoeol();
|
||||
mvprintw(20, 0, "Item selected is : %s",
|
||||
item_name(current_item(my_menu)));
|
||||
pos_menu_cursor(my_menu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
unpost_menu(my_menu);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
free_item(my_items[i]);
|
||||
free_menu(my_menu);
|
||||
endwin();
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#include <curses.h>
|
||||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Exit",
|
||||
};
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
int n_choices, i;
|
||||
ITEM *cur_item;
|
||||
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
|
||||
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
my_items[n_choices] = (ITEM *)NULL;
|
||||
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
post_menu(my_menu);
|
||||
refresh();
|
||||
|
||||
while((c = getch()) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case 10: /* Enter */
|
||||
cur_item = current_item(my_menu);
|
||||
move(LINES - 2, 0);
|
||||
clrtoeol();
|
||||
mvprintw(LINES - 2, 0, "You have chosen %d item with name %s and description %s",
|
||||
item_index(cur_item) + 1, item_name(cur_item),
|
||||
item_description(cur_item));
|
||||
|
||||
refresh();
|
||||
pos_menu_cursor(my_menu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free_item(my_items[0]);
|
||||
free_item(my_items[1]);
|
||||
free_menu(my_menu);
|
||||
endwin();
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#include <curses.h>
|
||||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1", "Choice 2", "Choice 3", "Choice 4", "Choice 5",
|
||||
"Choice 6", "Choice 7", "Choice 8", "Choice 9", "Choice 10",
|
||||
"Choice 11", "Choice 12", "Choice 13", "Choice 14", "Choice 15",
|
||||
"Choice 16", "Choice 17", "Choice 18", "Choice 19", "Choice 20",
|
||||
"Exit",
|
||||
(char *)NULL,
|
||||
};
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
WINDOW *my_menu_win;
|
||||
int n_choices, i;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
/* Create items */
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
|
||||
/* Crate menu */
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
|
||||
/* Set menu option not to show the description */
|
||||
menu_opts_off(my_menu, O_SHOWDESC);
|
||||
|
||||
/* Create the window to be associated with the menu */
|
||||
my_menu_win = newwin(10, 70, 4, 4);
|
||||
keypad(my_menu_win, TRUE);
|
||||
|
||||
/* Set main window and sub window */
|
||||
set_menu_win(my_menu, my_menu_win);
|
||||
set_menu_sub(my_menu, derwin(my_menu_win, 6, 68, 3, 1));
|
||||
set_menu_format(my_menu, 5, 3);
|
||||
set_menu_mark(my_menu, " * ");
|
||||
|
||||
/* Print a border around the main window and print a title */
|
||||
box(my_menu_win, 0, 0);
|
||||
|
||||
attron(COLOR_PAIR(2));
|
||||
mvprintw(LINES - 3, 0, "Use PageUp and PageDown to scroll");
|
||||
mvprintw(LINES - 2, 0, "Use Arrow Keys to navigate (F1 to Exit)");
|
||||
attroff(COLOR_PAIR(2));
|
||||
refresh();
|
||||
|
||||
/* Post the menu */
|
||||
post_menu(my_menu);
|
||||
wrefresh(my_menu_win);
|
||||
|
||||
while((c = wgetch(my_menu_win)) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
menu_driver(my_menu, REQ_LEFT_ITEM);
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
menu_driver(my_menu, REQ_RIGHT_ITEM);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
menu_driver(my_menu, REQ_SCR_DPAGE);
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
menu_driver(my_menu, REQ_SCR_UPAGE);
|
||||
break;
|
||||
}
|
||||
wrefresh(my_menu_win);
|
||||
}
|
||||
|
||||
/* Unpost and free all the memory taken up */
|
||||
unpost_menu(my_menu);
|
||||
free_menu(my_menu);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
free_item(my_items[i]);
|
||||
endwin();
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
#include <curses.h>
|
||||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Choice 5",
|
||||
"Choice 6",
|
||||
"Choice 7",
|
||||
"Choice 8",
|
||||
"Choice 9",
|
||||
"Choice 10",
|
||||
"Exit",
|
||||
(char *)NULL,
|
||||
};
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
WINDOW *my_menu_win;
|
||||
int n_choices, i;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
/* Create items */
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
|
||||
/* Crate menu */
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
|
||||
/* Create the window to be associated with the menu */
|
||||
my_menu_win = newwin(10, 40, 4, 4);
|
||||
keypad(my_menu_win, TRUE);
|
||||
|
||||
/* Set main window and sub window */
|
||||
set_menu_win(my_menu, my_menu_win);
|
||||
set_menu_sub(my_menu, derwin(my_menu_win, 6, 38, 3, 1));
|
||||
set_menu_format(my_menu, 5, 1);
|
||||
|
||||
/* Set menu mark to the string " * " */
|
||||
set_menu_mark(my_menu, " * ");
|
||||
|
||||
/* Print a border around the main window and print a title */
|
||||
box(my_menu_win, 0, 0);
|
||||
print_in_middle(my_menu_win, 1, 0, 40, "My Menu", COLOR_PAIR(1));
|
||||
mvwaddch(my_menu_win, 2, 0, ACS_LTEE);
|
||||
mvwhline(my_menu_win, 2, 1, ACS_HLINE, 38);
|
||||
mvwaddch(my_menu_win, 2, 39, ACS_RTEE);
|
||||
|
||||
/* Post the menu */
|
||||
post_menu(my_menu);
|
||||
wrefresh(my_menu_win);
|
||||
|
||||
attron(COLOR_PAIR(2));
|
||||
mvprintw(LINES - 2, 0, "Use PageUp and PageDown to scoll down or up a page of items");
|
||||
mvprintw(LINES - 1, 0, "Arrow Keys to navigate (F1 to Exit)");
|
||||
attroff(COLOR_PAIR(2));
|
||||
refresh();
|
||||
|
||||
while((c = wgetch(my_menu_win)) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case KEY_NPAGE:
|
||||
menu_driver(my_menu, REQ_SCR_DPAGE);
|
||||
break;
|
||||
case KEY_PPAGE:
|
||||
menu_driver(my_menu, REQ_SCR_UPAGE);
|
||||
break;
|
||||
}
|
||||
wrefresh(my_menu_win);
|
||||
}
|
||||
|
||||
/* Unpost and free all the memory taken up */
|
||||
unpost_menu(my_menu);
|
||||
free_menu(my_menu);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
free_item(my_items[i]);
|
||||
endwin();
|
||||
}
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
wattron(win, color);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
wattroff(win, color);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#include <curses.h>
|
||||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Exit",
|
||||
};
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
int n_choices, i;
|
||||
ITEM *cur_item;
|
||||
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
|
||||
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
my_items[n_choices] = (ITEM *)NULL;
|
||||
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
mvprintw(LINES - 2, 0, "F1 to Exit");
|
||||
post_menu(my_menu);
|
||||
refresh();
|
||||
|
||||
while((c = getch()) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free_item(my_items[0]);
|
||||
free_item(my_items[1]);
|
||||
free_menu(my_menu);
|
||||
endwin();
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#include <curses.h>
|
||||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Choice 5",
|
||||
"Choice 6",
|
||||
"Choice 7",
|
||||
"Exit",
|
||||
};
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
int n_choices, i;
|
||||
ITEM *cur_item;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize items */
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
my_items[n_choices] = (ITEM *)NULL;
|
||||
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
|
||||
/* Make the menu multi valued */
|
||||
menu_opts_off(my_menu, O_ONEVALUE);
|
||||
|
||||
mvprintw(LINES - 3, 0, "Use <SPACE> to select or unselect an item.");
|
||||
mvprintw(LINES - 2, 0, "<ENTER> to see presently selected items(F1 to Exit)");
|
||||
post_menu(my_menu);
|
||||
refresh();
|
||||
|
||||
while((c = getch()) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case ' ':
|
||||
menu_driver(my_menu, REQ_TOGGLE_ITEM);
|
||||
break;
|
||||
case 10: /* Enter */
|
||||
{ char temp[200];
|
||||
ITEM **items;
|
||||
|
||||
items = menu_items(my_menu);
|
||||
temp[0] = '\0';
|
||||
for(i = 0; i < item_count(my_menu); ++i)
|
||||
if(item_value(items[i]) == TRUE)
|
||||
{ strcat(temp, item_name(items[i]));
|
||||
strcat(temp, " ");
|
||||
}
|
||||
move(20, 0);
|
||||
clrtoeol();
|
||||
mvprintw(20, 0, temp);
|
||||
refresh();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free_item(my_items[0]);
|
||||
free_item(my_items[1]);
|
||||
free_menu(my_menu);
|
||||
endwin();
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#include <curses.h>
|
||||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Choice 5",
|
||||
"Choice 6",
|
||||
"Choice 7",
|
||||
"Exit",
|
||||
};
|
||||
void func(char *name);
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
int n_choices, i;
|
||||
ITEM *cur_item;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(3, COLOR_MAGENTA, COLOR_BLACK);
|
||||
|
||||
/* Initialize items */
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
{ my_items[i] = new_item(choices[i], choices[i]);
|
||||
/* Set the user pointer */
|
||||
set_item_userptr(my_items[i], func);
|
||||
}
|
||||
my_items[n_choices] = (ITEM *)NULL;
|
||||
|
||||
/* Create menu */
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
|
||||
/* Post the menu */
|
||||
mvprintw(LINES - 3, 0, "Press <ENTER> to see the option selected");
|
||||
mvprintw(LINES - 2, 0, "Up and Down arrow keys to naviage (F1 to Exit)");
|
||||
post_menu(my_menu);
|
||||
refresh();
|
||||
|
||||
while((c = getch()) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
case 10: /* Enter */
|
||||
{ ITEM *cur;
|
||||
void (*p)(char *);
|
||||
|
||||
cur = current_item(my_menu);
|
||||
p = item_userptr(cur);
|
||||
p((char *)item_name(cur));
|
||||
pos_menu_cursor(my_menu);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
unpost_menu(my_menu);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
free_item(my_items[i]);
|
||||
free_menu(my_menu);
|
||||
endwin();
|
||||
}
|
||||
|
||||
void func(char *name)
|
||||
{ move(20, 0);
|
||||
clrtoeol();
|
||||
mvprintw(20, 0, "Item selected is : %s", name);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
#include <menu.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define CTRLD 4
|
||||
|
||||
char *choices[] = {
|
||||
"Choice 1",
|
||||
"Choice 2",
|
||||
"Choice 3",
|
||||
"Choice 4",
|
||||
"Exit",
|
||||
(char *)NULL,
|
||||
};
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
|
||||
|
||||
int main()
|
||||
{ ITEM **my_items;
|
||||
int c;
|
||||
MENU *my_menu;
|
||||
WINDOW *my_menu_win;
|
||||
int n_choices, i;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
|
||||
/* Create items */
|
||||
n_choices = ARRAY_SIZE(choices);
|
||||
my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
my_items[i] = new_item(choices[i], choices[i]);
|
||||
|
||||
/* Crate menu */
|
||||
my_menu = new_menu((ITEM **)my_items);
|
||||
|
||||
/* Create the window to be associated with the menu */
|
||||
my_menu_win = newwin(10, 40, 4, 4);
|
||||
keypad(my_menu_win, TRUE);
|
||||
|
||||
/* Set main window and sub window */
|
||||
set_menu_win(my_menu, my_menu_win);
|
||||
set_menu_sub(my_menu, derwin(my_menu_win, 6, 38, 3, 1));
|
||||
|
||||
/* Set menu mark to the string " * " */
|
||||
set_menu_mark(my_menu, " * ");
|
||||
|
||||
/* Print a border around the main window and print a title */
|
||||
box(my_menu_win, 0, 0);
|
||||
print_in_middle(my_menu_win, 1, 0, 40, "My Menu", COLOR_PAIR(1));
|
||||
mvwaddch(my_menu_win, 2, 0, ACS_LTEE);
|
||||
mvwhline(my_menu_win, 2, 1, ACS_HLINE, 38);
|
||||
mvwaddch(my_menu_win, 2, 39, ACS_RTEE);
|
||||
mvprintw(LINES - 2, 0, "F1 to exit");
|
||||
refresh();
|
||||
|
||||
/* Post the menu */
|
||||
post_menu(my_menu);
|
||||
wrefresh(my_menu_win);
|
||||
|
||||
while((c = wgetch(my_menu_win)) != KEY_F(1))
|
||||
{ switch(c)
|
||||
{ case KEY_DOWN:
|
||||
menu_driver(my_menu, REQ_DOWN_ITEM);
|
||||
break;
|
||||
case KEY_UP:
|
||||
menu_driver(my_menu, REQ_UP_ITEM);
|
||||
break;
|
||||
}
|
||||
wrefresh(my_menu_win);
|
||||
}
|
||||
|
||||
/* Unpost and free all the memory taken up */
|
||||
unpost_menu(my_menu);
|
||||
free_menu(my_menu);
|
||||
for(i = 0; i < n_choices; ++i)
|
||||
free_item(my_items[i]);
|
||||
endwin();
|
||||
}
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
wattron(win, color);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
wattroff(win, color);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
# Makefile for JustForFun Files
|
||||
|
||||
# A few variables
|
||||
|
||||
CC=gcc
|
||||
LIBS=-lpanel -lncurses
|
||||
|
||||
SRC_DIR=.
|
||||
EXE_DIR=../demo/exe
|
||||
|
||||
EXES = \
|
||||
${EXE_DIR}/panel_browse \
|
||||
${EXE_DIR}/panel_hide \
|
||||
${EXE_DIR}/panel_resize \
|
||||
${EXE_DIR}/panel_simple
|
||||
|
||||
${EXE_DIR}/%: %.o
|
||||
${CC} -o $@ $< ${LIBS}
|
||||
|
||||
%.o: ${SRC_DIR}/%.c
|
||||
${CC} -o $@ -c $<
|
||||
|
||||
all: ${EXES}
|
||||
|
||||
|
||||
clean:
|
||||
@rm -f ${EXES}
|
|
@ -0,0 +1,8 @@
|
|||
Description of files
|
||||
--------------------
|
||||
panels
|
||||
|
|
||||
|----> panel_browse.c -- Panel browsing through tab. Usage of user pointer
|
||||
|----> panel_hide.c -- Hiding and Un hiding of panels
|
||||
|----> panel_resize.c -- Moving and resizing of panels
|
||||
|----> panel_simple.c -- A simple panel example
|
|
@ -0,0 +1,117 @@
|
|||
#include <panel.h>
|
||||
|
||||
#define NLINES 10
|
||||
#define NCOLS 40
|
||||
|
||||
void init_wins(WINDOW **wins, int n);
|
||||
void win_show(WINDOW *win, char *label, int label_color);
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
|
||||
|
||||
int main()
|
||||
{ WINDOW *my_wins[3];
|
||||
PANEL *my_panels[3];
|
||||
PANEL *top;
|
||||
int ch;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize all the colors */
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(3, COLOR_BLUE, COLOR_BLACK);
|
||||
init_pair(4, COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
init_wins(my_wins, 3);
|
||||
|
||||
/* Attach a panel to each window */ /* Order is bottom up */
|
||||
my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
|
||||
my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
|
||||
my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
|
||||
|
||||
/* Set up the user pointers to the next panel */
|
||||
set_panel_userptr(my_panels[0], my_panels[1]);
|
||||
set_panel_userptr(my_panels[1], my_panels[2]);
|
||||
set_panel_userptr(my_panels[2], my_panels[0]);
|
||||
|
||||
/* Update the stacking order. 2nd panel will be on top */
|
||||
update_panels();
|
||||
|
||||
/* Show it on the screen */
|
||||
attron(COLOR_PAIR(4));
|
||||
mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");
|
||||
attroff(COLOR_PAIR(4));
|
||||
doupdate();
|
||||
|
||||
top = my_panels[2];
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case 9:
|
||||
top = (PANEL *)panel_userptr(top);
|
||||
top_panel(top);
|
||||
break;
|
||||
}
|
||||
update_panels();
|
||||
doupdate();
|
||||
}
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Put all the windows */
|
||||
void init_wins(WINDOW **wins, int n)
|
||||
{ int x, y, i;
|
||||
char label[80];
|
||||
|
||||
y = 2;
|
||||
x = 10;
|
||||
for(i = 0; i < n; ++i)
|
||||
{ wins[i] = newwin(NLINES, NCOLS, y, x);
|
||||
sprintf(label, "Window Number %d", i + 1);
|
||||
win_show(wins[i], label, i + 1);
|
||||
y += 3;
|
||||
x += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/* Show the window with a border and a label */
|
||||
void win_show(WINDOW *win, char *label, int label_color)
|
||||
{ int startx, starty, height, width;
|
||||
|
||||
getbegyx(win, starty, startx);
|
||||
getmaxyx(win, height, width);
|
||||
|
||||
box(win, 0, 0);
|
||||
mvwaddch(win, 2, 0, ACS_LTEE);
|
||||
mvwhline(win, 2, 1, ACS_HLINE, width - 2);
|
||||
mvwaddch(win, 2, width - 1, ACS_RTEE);
|
||||
|
||||
print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
|
||||
}
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
wattron(win, color);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
wattroff(win, color);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
#include <panel.h>
|
||||
|
||||
typedef struct _PANEL_DATA {
|
||||
int hide; /* TRUE if panel is hidden */
|
||||
}PANEL_DATA;
|
||||
|
||||
#define NLINES 10
|
||||
#define NCOLS 40
|
||||
|
||||
void init_wins(WINDOW **wins, int n);
|
||||
void win_show(WINDOW *win, char *label, int label_color);
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
|
||||
|
||||
int main()
|
||||
{ WINDOW *my_wins[3];
|
||||
PANEL *my_panels[3];
|
||||
PANEL_DATA panel_datas[3];
|
||||
PANEL_DATA *temp;
|
||||
int ch;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize all the colors */
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(3, COLOR_BLUE, COLOR_BLACK);
|
||||
init_pair(4, COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
init_wins(my_wins, 3);
|
||||
|
||||
/* Attach a panel to each window */ /* Order is bottom up */
|
||||
my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
|
||||
my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
|
||||
my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
|
||||
|
||||
/* Initialize panel datas saying that nothing is hidden */
|
||||
panel_datas[0].hide = FALSE;
|
||||
panel_datas[1].hide = FALSE;
|
||||
panel_datas[2].hide = FALSE;
|
||||
|
||||
set_panel_userptr(my_panels[0], &panel_datas[0]);
|
||||
set_panel_userptr(my_panels[1], &panel_datas[1]);
|
||||
set_panel_userptr(my_panels[2], &panel_datas[2]);
|
||||
|
||||
/* Update the stacking order. 2nd panel will be on top */
|
||||
update_panels();
|
||||
|
||||
/* Show it on the screen */
|
||||
attron(COLOR_PAIR(4));
|
||||
mvprintw(LINES - 3, 0, "Show or Hide a window with 'a'(first window) 'b'(Second Window) 'c'(Third Window)");
|
||||
mvprintw(LINES - 2, 0, "F1 to Exit");
|
||||
|
||||
attroff(COLOR_PAIR(4));
|
||||
doupdate();
|
||||
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case 'a':
|
||||
temp = (PANEL_DATA *)panel_userptr(my_panels[0]);
|
||||
if(temp->hide == FALSE)
|
||||
{ hide_panel(my_panels[0]);
|
||||
temp->hide = TRUE;
|
||||
}
|
||||
else
|
||||
{ show_panel(my_panels[0]);
|
||||
temp->hide = FALSE;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
temp = (PANEL_DATA *)panel_userptr(my_panels[1]);
|
||||
if(temp->hide == FALSE)
|
||||
{ hide_panel(my_panels[1]);
|
||||
temp->hide = TRUE;
|
||||
}
|
||||
else
|
||||
{ show_panel(my_panels[1]);
|
||||
temp->hide = FALSE;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
temp = (PANEL_DATA *)panel_userptr(my_panels[2]);
|
||||
if(temp->hide == FALSE)
|
||||
{ hide_panel(my_panels[2]);
|
||||
temp->hide = TRUE;
|
||||
}
|
||||
else
|
||||
{ show_panel(my_panels[2]);
|
||||
temp->hide = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
update_panels();
|
||||
doupdate();
|
||||
}
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Put all the windows */
|
||||
void init_wins(WINDOW **wins, int n)
|
||||
{ int x, y, i;
|
||||
char label[80];
|
||||
|
||||
y = 2;
|
||||
x = 10;
|
||||
for(i = 0; i < n; ++i)
|
||||
{ wins[i] = newwin(NLINES, NCOLS, y, x);
|
||||
sprintf(label, "Window Number %d", i + 1);
|
||||
win_show(wins[i], label, i + 1);
|
||||
y += 3;
|
||||
x += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/* Show the window with a border and a label */
|
||||
void win_show(WINDOW *win, char *label, int label_color)
|
||||
{ int startx, starty, height, width;
|
||||
|
||||
getbegyx(win, starty, startx);
|
||||
getmaxyx(win, height, width);
|
||||
|
||||
box(win, 0, 0);
|
||||
mvwaddch(win, 2, 0, ACS_LTEE);
|
||||
mvwhline(win, 2, 1, ACS_HLINE, width - 2);
|
||||
mvwaddch(win, 2, width - 1, ACS_RTEE);
|
||||
|
||||
print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
|
||||
}
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
wattron(win, color);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
wattroff(win, color);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
#include <panel.h>
|
||||
|
||||
typedef struct _PANEL_DATA {
|
||||
int x, y, w, h;
|
||||
char label[80];
|
||||
int label_color;
|
||||
PANEL *next;
|
||||
}PANEL_DATA;
|
||||
|
||||
#define NLINES 10
|
||||
#define NCOLS 40
|
||||
|
||||
void init_wins(WINDOW **wins, int n);
|
||||
void win_show(WINDOW *win, char *label, int label_color);
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
|
||||
void set_user_ptrs(PANEL **panels, int n);
|
||||
|
||||
int main()
|
||||
{ WINDOW *my_wins[3];
|
||||
PANEL *my_panels[3];
|
||||
PANEL_DATA *top;
|
||||
PANEL *stack_top;
|
||||
WINDOW *temp_win, *old_win;
|
||||
int ch;
|
||||
int newx, newy, neww, newh;
|
||||
int size = FALSE, move = FALSE;
|
||||
|
||||
/* Initialize curses */
|
||||
initscr();
|
||||
start_color();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
|
||||
/* Initialize all the colors */
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||
init_pair(2, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(3, COLOR_BLUE, COLOR_BLACK);
|
||||
init_pair(4, COLOR_CYAN, COLOR_BLACK);
|
||||
|
||||
init_wins(my_wins, 3);
|
||||
|
||||
/* Attach a panel to each window */ /* Order is bottom up */
|
||||
my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
|
||||
my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
|
||||
my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
|
||||
|
||||
set_user_ptrs(my_panels, 3);
|
||||
/* Update the stacking order. 2nd panel will be on top */
|
||||
update_panels();
|
||||
|
||||
/* Show it on the screen */
|
||||
attron(COLOR_PAIR(4));
|
||||
mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing");
|
||||
mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");
|
||||
attroff(COLOR_PAIR(4));
|
||||
doupdate();
|
||||
|
||||
stack_top = my_panels[2];
|
||||
top = (PANEL_DATA *)panel_userptr(stack_top);
|
||||
newx = top->x;
|
||||
newy = top->y;
|
||||
neww = top->w;
|
||||
newh = top->h;
|
||||
while((ch = getch()) != KEY_F(1))
|
||||
{ switch(ch)
|
||||
{ case 9: /* Tab */
|
||||
top = (PANEL_DATA *)panel_userptr(stack_top);
|
||||
top_panel(top->next);
|
||||
stack_top = top->next;
|
||||
top = (PANEL_DATA *)panel_userptr(stack_top);
|
||||
newx = top->x;
|
||||
newy = top->y;
|
||||
neww = top->w;
|
||||
newh = top->h;
|
||||
break;
|
||||
case 'r': /* Re-Size*/
|
||||
size = TRUE;
|
||||
attron(COLOR_PAIR(4));
|
||||
mvprintw(LINES - 4, 0, "Entered Resizing :Use Arrow Keys to resize and press <ENTER> to end resizing");
|
||||
refresh();
|
||||
attroff(COLOR_PAIR(4));
|
||||
break;
|
||||
case 'm': /* Move */
|
||||
attron(COLOR_PAIR(4));
|
||||
mvprintw(LINES - 4, 0, "Entered Moving: Use Arrow Keys to Move and press <ENTER> to end moving");
|
||||
refresh();
|
||||
attroff(COLOR_PAIR(4));
|
||||
move = TRUE;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if(size == TRUE)
|
||||
{ --newx;
|
||||
++neww;
|
||||
}
|
||||
if(move == TRUE)
|
||||
--newx;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if(size == TRUE)
|
||||
{ ++newx;
|
||||
--neww;
|
||||
}
|
||||
if(move == TRUE)
|
||||
++newx;
|
||||
break;
|
||||
case KEY_UP:
|
||||
if(size == TRUE)
|
||||
{ --newy;
|
||||
++newh;
|
||||
}
|
||||
if(move == TRUE)
|
||||
--newy;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if(size == TRUE)
|
||||
{ ++newy;
|
||||
--newh;
|
||||
}
|
||||
if(move == TRUE)
|
||||
++newy;
|
||||
break;
|
||||
case 10: /* Enter */
|
||||
move(LINES - 4, 0);
|
||||
clrtoeol();
|
||||
refresh();
|
||||
if(size == TRUE)
|
||||
{ old_win = panel_window(stack_top);
|
||||
temp_win = newwin(newh, neww, newy, newx);
|
||||
replace_panel(stack_top, temp_win);
|
||||
win_show(temp_win, top->label, top->label_color);
|
||||
delwin(old_win);
|
||||
size = FALSE;
|
||||
}
|
||||
if(move == TRUE)
|
||||
{ move_panel(stack_top, newy, newx);
|
||||
move = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
attron(COLOR_PAIR(4));
|
||||
mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing");
|
||||
mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");
|
||||
attroff(COLOR_PAIR(4));
|
||||
refresh();
|
||||
update_panels();
|
||||
doupdate();
|
||||
}
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Put all the windows */
|
||||
void init_wins(WINDOW **wins, int n)
|
||||
{ int x, y, i;
|
||||
char label[80];
|
||||
|
||||
y = 2;
|
||||
x = 10;
|
||||
for(i = 0; i < n; ++i)
|
||||
{ wins[i] = newwin(NLINES, NCOLS, y, x);
|
||||
sprintf(label, "Window Number %d", i + 1);
|
||||
win_show(wins[i], label, i + 1);
|
||||
y += 3;
|
||||
x += 7;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the PANEL_DATA structures for individual panels */
|
||||
void set_user_ptrs(PANEL **panels, int n)
|
||||
{ PANEL_DATA *ptrs;
|
||||
WINDOW *win;
|
||||
int x, y, w, h, i;
|
||||
char temp[80];
|
||||
|
||||
ptrs = (PANEL_DATA *)calloc(n, sizeof(PANEL_DATA));
|
||||
|
||||
for(i = 0;i < n; ++i)
|
||||
{ win = panel_window(panels[i]);
|
||||
getbegyx(win, y, x);
|
||||
getmaxyx(win, h, w);
|
||||
ptrs[i].x = x;
|
||||
ptrs[i].y = y;
|
||||
ptrs[i].w = w;
|
||||
ptrs[i].h = h;
|
||||
sprintf(temp, "Window Number %d", i + 1);
|
||||
strcpy(ptrs[i].label, temp);
|
||||
ptrs[i].label_color = i + 1;
|
||||
if(i + 1 == n)
|
||||
ptrs[i].next = panels[0];
|
||||
else
|
||||
ptrs[i].next = panels[i + 1];
|
||||
set_panel_userptr(panels[i], &ptrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Show the window with a border and a label */
|
||||
void win_show(WINDOW *win, char *label, int label_color)
|
||||
{ int startx, starty, height, width;
|
||||
|
||||
getbegyx(win, starty, startx);
|
||||
getmaxyx(win, height, width);
|
||||
|
||||
box(win, 0, 0);
|
||||
mvwaddch(win, 2, 0, ACS_LTEE);
|
||||
mvwhline(win, 2, 1, ACS_HLINE, width - 2);
|
||||
mvwaddch(win, 2, width - 1, ACS_RTEE);
|
||||
|
||||
print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
|
||||
}
|
||||
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
{ int length, x, y;
|
||||
float temp;
|
||||
|
||||
if(win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if(startx != 0)
|
||||
x = startx;
|
||||
if(starty != 0)
|
||||
y = starty;
|
||||
if(width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length)/ 2;
|
||||
x = startx + (int)temp;
|
||||
wattron(win, color);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
wattroff(win, color);
|
||||
refresh();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#include <panel.h>
|
||||
|
||||
int main()
|
||||
{ WINDOW *my_wins[3];
|
||||
PANEL *my_panels[3];
|
||||
int lines = 10, cols = 40, y = 2, x = 4, i;
|
||||
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
|
||||
/* Create windows for the panels */
|
||||
my_wins[0] = newwin(lines, cols, y, x);
|
||||
my_wins[1] = newwin(lines, cols, y + 1, x + 5);
|
||||
my_wins[2] = newwin(lines, cols, y + 2, x + 10);
|
||||
|
||||
/*
|
||||
* Create borders around the windows so that you can see the effect
|
||||
* of panels
|
||||
*/
|
||||
for(i = 0; i < 3; +++i)
|
||||
box(my_wins[i], 0, 0);
|
||||
|
||||
/* Attach a panel to each window */ /* Order is bottom up */
|
||||
my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
|
||||
my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
|
||||
my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
|
||||
|
||||
/* Update the stacking order. 2nd panel will be on top */
|
||||
update_panels();
|
||||
|
||||
/* Show it on the screen */
|
||||
doupdate();
|
||||
|
||||
getch();
|
||||
endwin();
|
||||
}
|
||||
|
|
@ -0,0 +1,360 @@
|
|||
<!doctype linuxdoc system>
|
||||
|
||||
<article>
|
||||
|
||||
<title>The VPN HOWTO
|
||||
<author>Arpad Magosanyi <mag@bunuel.tii.matav.hu> v0.2,7 Aug1997
|
||||
<date>v0.3, 2001-12-01
|
||||
|
||||
<p>
|
||||
<bf>Archived Document Notice:</bf> This document has been archived by the LDP
|
||||
because it does not apply to modern Linux systems. It is no longer
|
||||
being actively maintained.
|
||||
</p>
|
||||
|
||||
<sect>Changes
|
||||
<p>
|
||||
|
||||
The 'no controlling tty problem' -> -o 'BatchMode yes' by Zot O'Connor <zot@crl.com>
|
||||
|
||||
warning about kernel 2.0.30 by mag
|
||||
<sect>Blurb
|
||||
<p>
|
||||
|
||||
This is the Linux VPN howto, a collection of information on how to set up a Virtual Protected Network in Linux (and other unices in general).
|
||||
<sect1>Copyright
|
||||
<p>
|
||||
|
||||
This document is part of the Linux Documentation Project. The copyright notice is the following:
|
||||
<p>
|
||||
The VPN mini HOWTO written by me can be copied,
|
||||
distributed, and/or modified under the terms of the GNU Free Documentation
|
||||
License, Version 1.1 or any later version published by the Free Software
|
||||
Foundation; with the Invariant Section being the section entitled "About
|
||||
the ppp over ssh vpn technique", with any Front-Cover Text containing the p=
|
||||
hrase
|
||||
"Based on the work of Arpad Magosanyi", and with any Back-Cover Text.
|
||||
|
||||
<sect1>Disclaimer
|
||||
<p>
|
||||
|
||||
As usual: the author not responsible for any damage. For the correct wording, see the relevant part of the GNU GPL 0.1.1
|
||||
<sect1>Disclaimer
|
||||
<p>
|
||||
|
||||
We are dealing with security: you are not safe if you haven't got good security policy, and other rather boring things.
|
||||
<sect1>Credits
|
||||
<p>
|
||||
|
||||
Thanks to all of who has written the tools used.
|
||||
|
||||
Thanks to Zot O'Connor <zot@crl.com> for pointing out the "no controlling tty" problem, and it's solution.
|
||||
<sect1>State of this document
|
||||
<p>
|
||||
|
||||
This is very preliminary. You should have thorough knowledge of administrating IP, at least some knowledge of firewalls, ppp and ssh. You should know them anyway if you want to set up a VPN. I just decided to write down my experiences not to forget them. There are possibly some security holes indeed. To be fair I've tried it on hosts configured as routers not firewalls, saying: It's simple from that point.
|
||||
<sect1>Related documentations
|
||||
<p>
|
||||
<itemize>
|
||||
<item>The Linux Firewall-HOWTO /usr/doc/HOWTO/Firewall-HOWTO
|
||||
<item>The Linux PPP-HOWTO /usr/doc/HOWTO/PPP-HOWTO.gz
|
||||
<item>The ssh documentations /usr/doc/ssh/*
|
||||
<item>The Linux Network Admins' Guide
|
||||
<item>NIST Computer Security Special Publications http://csrc.ncsl.nist.gov/nistpubs/
|
||||
<item>Firewall list (majordomo@greatcircle.com)
|
||||
</itemize>
|
||||
<sect>Introduction
|
||||
<p>
|
||||
|
||||
As firewalls are in more and more widely use in internet and intranet security, the ability to do nice VPNs is important. Here are my experiences. Comments are welcome.
|
||||
<sect1>Naming conventions
|
||||
<p>
|
||||
|
||||
I will use the terms "master firewall" and "slave firewall", though making a VPN has nothing to do with client-server architecture. I simply refer to them as the active and passive participants of the connection's setup. The host which is starts the setup will be referred as the master, and the passive participant will be the slave.
|
||||
<sect>Doing it
|
||||
<p>
|
||||
<sect1>Planning
|
||||
<p>
|
||||
|
||||
Before you start to set up your system, you should know the networking details. I assume you have two firewalls protecting one intranet per firewall, and they are both connected to the internet. So now you should have two network interfaces (at least) per firewall. Take a sheet of paper, write down their IP addresses and network mask. You will need one more IP adresses per firewall for the VPN you want to do now. Those addresses should be outside of your existing subnets. I suggest using addresses from the "private" address ranges. They are the followings:
|
||||
<itemize>
|
||||
<item>10.0.0.0 - 10.255.255.255
|
||||
<item>172.16.0.0 - 172.31.255.255
|
||||
<item>192.168.0.0 - 192.168.255.255
|
||||
</itemize>
|
||||
|
||||
For the sake of example, here's a sample configuration: The two bastions are called fellini and polanski. They have one interface for the internet (-out), one for the intranet (-in), and one for the vpn (-vpn). The addresses and netmasks:
|
||||
<itemize>
|
||||
<item>fellini-out: 193.6.34.12 255.255.255.0
|
||||
<item>fellini-in: 193.6.35.12 255.255.255.0
|
||||
<item>fellini-vpn: 192.168.0.1 point-to-point
|
||||
<item>polanski-out: 193.6.36.12 255.255.255.0
|
||||
<item>polanski-in: 193.6.37.12 255.255.255.0
|
||||
<item>polanski-vpn: 192.168.0.2 point-to-point
|
||||
</itemize>
|
||||
|
||||
So we have the plan.
|
||||
<sect1>Gathering the tools
|
||||
<p>
|
||||
|
||||
You will need a
|
||||
<itemize>
|
||||
<item>Linux firewall
|
||||
<item>kernel
|
||||
<item>very minimal configuration
|
||||
<item>ipfwadm
|
||||
<item>fwtk
|
||||
<item>Tools for the VPN
|
||||
<item>ssh
|
||||
<item>pppd
|
||||
<item>sudo
|
||||
<item>pty-redir
|
||||
</itemize>
|
||||
|
||||
Current versions:
|
||||
<itemize>
|
||||
<item>kernel: 2.0.29 Use a stable kernel, and it must be newer than 2.0.20, because the ping'o'death bug. At the time of writing 2.0.30 is the last "stable" kernel, but it has some bugs. If you want to have the fast and cool networking code introduced in it, try a prepatch. the 3rd is working for me nicely.
|
||||
<item>base system: I prefer Debian. YMMV. You absolutely don't want to use any big packages, and you never even tought of using sendmail, of course. You also definitely don't want to enable telnet, ftp, and the 'r' commands (as usual in case of any other unix hosts).
|
||||
<item>ipfwadm: I've used 2.3.0
|
||||
<item>fwtk: I've used 1.3
|
||||
<item>ssh: >= 1.2.20. There are problems with the underlying protocol in the older versions.
|
||||
<item>pppd: I've used 2.2.0f for the tests, but I'm not sure if is it secure, this is why I turned the setuid bit off, and used sudo to launch it.
|
||||
<item>sudo: 1.5.2 the newest I am aware of
|
||||
<item>pty-redir: It is written by me. Try ftp://ftp.vein.hu/ssa/contrib/mag/pty-redir-0.1.tar.gz. Its version number is 0.1 now. Tell me it there is any problem with it.
|
||||
</itemize>
|
||||
<sect1>Compile and install
|
||||
<p>
|
||||
|
||||
Compile or otherwise install the gathered tools. Look at every one's documentation (and the firewall-howto) for details. Now we have the tools.
|
||||
<sect1>Configure the other subsystems
|
||||
<p>
|
||||
|
||||
Configure your firewall rules, etc. You need to enable ssh traffic between the two firewll hosts. It means a connection to port 22 on the slave from the master. Start sshd on the slave and verify if you can login. This step is untested, please tell me your results.
|
||||
<sect1>Set up the accounts for the VPN
|
||||
<p>
|
||||
|
||||
Create an account on the slave firewall use your favourite tool (e.g. vi, mkdir, chown, chmod) you might create an account on the master also, but I think you want to set up the connection at boot time, so your ordinary root account will do. Can anyone point out risks on using the root account on the master?
|
||||
<sect1>Generate an ssh key for your master account
|
||||
<p>
|
||||
|
||||
Use the ssh-keygen program. Set empty password for the private key if you want to do automatic setup of the VPN.
|
||||
<sect1>Set up automatic ssh login for the slave account
|
||||
<p>
|
||||
|
||||
Copy the newly generated public key in the slave account under .ssh/authorized_keys, and set up file permissions like the following:
|
||||
<verb>
|
||||
drwx------ 2 slave slave 1024 Apr 7 23:49 ./
|
||||
drwx------ 4 slave slave 1024 Apr 24 14:05 ../
|
||||
-rwx------ 1 slave slave 328 Apr 7 03:04 authorized_keys
|
||||
-rw------- 1 slave slave 660 Apr 14 15:23 known_hosts
|
||||
-rw------- 1 slave slave 512 Apr 21 10:03 random_seed
|
||||
</verb>
|
||||
|
||||
The first row being ˜slave/.ssh, and the second is ˜slave.
|
||||
<sect1>Tighten ssh security on the bastions.
|
||||
<p>
|
||||
|
||||
It means the followings on my setup in sshd_conf:
|
||||
<verb>
|
||||
PermitRootLogin no
|
||||
IgnoreRhosts yes
|
||||
StrictModes yes
|
||||
QuietMode no
|
||||
FascistLogging yes
|
||||
KeepAlive yes
|
||||
RhostsAuthentication no
|
||||
RhostsRSAAuthentication no
|
||||
RSAAuthentication yes
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
</verb>
|
||||
|
||||
Password authentication is turned off, so login is only possible with authorized keys. (You've turned off telnet and the 'r' commands of course).
|
||||
<sect1>Enable execution of ppp and route for both accounts.
|
||||
<p>
|
||||
|
||||
As the master account is the root in my case, it has nothing to do. For the slave account, the following lines appear in /etc/sudoers:
|
||||
<verb>
|
||||
Cmnd_Alias VPN=/usr/sbin/pppd,/usr/local/vpn/route
|
||||
slave ALL=NOPASSWD: VPN
|
||||
</verb>
|
||||
|
||||
As you can see, I am using some scripts to set up ppp and the routing tables on the slave host.
|
||||
<sect1>Do the scripting
|
||||
<p>
|
||||
|
||||
On the master host there is a full-blown init script I am using:
|
||||
<verb>
|
||||
#! /bin/sh
|
||||
# skeleton example file to build /etc/init.d/ scripts.
|
||||
# This file should be used to construct scripts for /etc/init.d.
|
||||
#
|
||||
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
|
||||
# Modified for Debian GNU/Linux
|
||||
# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
|
||||
#
|
||||
# Version: @(#)skeleton 1.6 11-Nov-1996 miquels@cistron.nl
|
||||
#
|
||||
|
||||
PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:
|
||||
PPPAPP=/home/slave/ppp
|
||||
ROUTEAPP=/home/slave/route
|
||||
PPPD=/usr/sbin/pppd
|
||||
NAME=VPN
|
||||
REDIR=/usr/local/bin/pty-redir
|
||||
SSH=/usr/bin/ssh
|
||||
MYPPPIP=192.168.0.1
|
||||
TARGETIP=192.168.0.2
|
||||
TARGETNET=193.6.37.0
|
||||
MYNET=193.6.35.0
|
||||
SLAVEWALL=polanski-out
|
||||
SLAVEACC=slave
|
||||
|
||||
test -f $PPPD || exit 0
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo setting up vpn
|
||||
$REDIR $SSH -o 'Batchmode yes' -t -l $SLAVEACC $SLAVEWALL sudo $PPPAPP >/tmp/device
|
||||
TTYNAME=`cat /tmp/device`
|
||||
echo tty is $TTYNAME
|
||||
sleep 10s
|
||||
if [ ! -z $TTYNAME ]
|
||||
then
|
||||
$PPPD $TTYNAME ${MYPPPIP}:${TARGETIP}
|
||||
else
|
||||
echo FAILED!
|
||||
logger "vpn setup failed"
|
||||
fi
|
||||
sleep 5s
|
||||
route add -net $TARGETNET gw $TARGETIP
|
||||
$SSH -o 'Batchmode yes' -l $SLAVEACC $SLAVEWALL sudo $ROUTEAPP
|
||||
;;
|
||||
stop)
|
||||
ps -ax | grep "ssh -t -l $SLAVEACC " | grep -v grep | awk '{print $1}' | xargs kill
|
||||
;;
|
||||
*)
|
||||
# echo "Usage: /etc/init.d/$NAME {start|stop|reload}"
|
||||
echo "Usage: /etc/init.d/$NAME {start|stop}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
</verb>
|
||||
|
||||
The slave uses one script for routing setup (/usr/local/vpn/route):
|
||||
<verb>
|
||||
#!/bin/bash
|
||||
/sbin/route add -net 193.6.35.0 gw 192.168.0.1
|
||||
</verb>
|
||||
|
||||
and its .ppprc consists of the following:
|
||||
<verb>
|
||||
passive
|
||||
</verb>
|
||||
<sect>Look at what's happening:
|
||||
<p>
|
||||
|
||||
The master logs in into the slave, starts pppd, and redirects this all thing into a local pty. It consists of the following steps:
|
||||
<itemize>
|
||||
<item>allocating a new pty
|
||||
<item>sshing into the slave
|
||||
<item>running pppd on the slave
|
||||
<item>the master runs pppd in this local pty
|
||||
<item>and sets up the routing table on the client.
|
||||
</itemize>
|
||||
|
||||
There are (not very tight) timing considerations involved, this is why that 'sleep 10s'.
|
||||
<sect>Doing it by hand.
|
||||
<p>
|
||||
<sect1>Logging in
|
||||
<p>
|
||||
|
||||
You've already tried if ssh works well, aren't you? If the slave refuses to log you in, read the logs. Perhaps there are problems with file permissions or the sshd setup.
|
||||
<sect1>Firing up ppp
|
||||
<p>
|
||||
|
||||
Log in into slave, and issue:
|
||||
<verb>sudo /usr/sbin/pppd passive
|
||||
|
||||
</verb>
|
||||
|
||||
You should see garbage coming at this point. If it works good, if not, there is some problem either with sudo, either with pppd. Look what the commands had said, and at the logs and at the <em>/etc/ppp/options</em>, and the <em>.ppprc </em>file. If it works, write this 'passive' word into .ppprc, and try again. To get rid off the garbage and continue working, press enter,'˜' and '^Z'. You should have the master's prompt now, and kill %1. See the section about tuning if you want to know more of the escape character.
|
||||
<sect1>Together the two
|
||||
<p>
|
||||
|
||||
Well, then
|
||||
<verb>ssh -l slave polanski sudo /usr/sbin/pppd
|
||||
|
||||
</verb>
|
||||
|
||||
should work also, and deliver the garbage right into your face.
|
||||
<sect1>Pty redirecting
|
||||
<p>
|
||||
|
||||
Try to redirect this whole thing this time:
|
||||
<verb>/usr/local/bin/pty-redir /usr/bin/ssh -l slave polanski sudo /usr/sbin/pppd
|
||||
|
||||
</verb>
|
||||
|
||||
Nice long sentence isn't it? You should use the full path into the ssh executable, as the pty-redir program allows only this form for security reasons. Now you've got a device name from the program. Let's say, you've got <em>/dev/ttyp0 </em> You can use the ps command to look what has happened. Look for 'p0'
|
||||
<sect1>Is anything on the device?
|
||||
<p>
|
||||
|
||||
Try
|
||||
<verb>/usr/sbin/pppd /dev/ttyp0 local 192.168.0.1:192.168.0.2
|
||||
|
||||
</verb>
|
||||
|
||||
to establish the connection. Look at the output of the ifconfig command to see if the device has established, and use ping to check your virtual net.
|
||||
<sect1>Setting up the routes
|
||||
<p>
|
||||
|
||||
Set up the routes on the master host, and on the slave also. Now you should be able to ping one host in one intranet from other host in the other intranet. Set up the additional firewalling rules. Now as you have the VPN, you can set up the rules concerning the connectivity of the two intranets.
|
||||
<sect>Tuning
|
||||
<p>
|
||||
<sect1>Configuration tuning
|
||||
<p>
|
||||
|
||||
As I said this HOWTO is mainly a quick memo on how I had set up a VPN. There are things in the configuration I didn't experiment yet. These things will go into their place when I try them, or anyone tells me "it works in the following way" The most important thing is that the connection ppp uses is not 8-bit yet. I believe it has something to do either with ssh configuration or the pty setup. In this configuration ssh uses the tilde (˜) character as an escape character. It might stop or slow down the communication, as any newline-tilde sequence causes ssh to give a prompt. Ssh documentation said: <On most systems, setting the escape character to ``none'' will also make the session transparent even if a tty is used.> The corresponding flag to ssh is '<em>-e</em>', and you can also set it in the configuration file.
|
||||
<sect1>Bandwith vs. cicles
|
||||
<p>
|
||||
|
||||
Creating anything virtual comes with utilization of real-world resources. A VPN eats up bandwidth and computing resources. The goal would be to get balance between the two. You can tune it with the '-C' switch or the 'CompressionLevel' option. You might try using another cipher, but I don't recommend it. Also note that the round-trip-time can be longer if you use better compression. Any experiments on it are welcome.
|
||||
<sect>Vulnerability analisis
|
||||
<p>
|
||||
|
||||
I try to cover here the vulnerability issues arising from this particular setup and VPNs in general. Any comments are warmly welcome.
|
||||
<itemize>
|
||||
<item>sudo: Well, I'm excessively using sudo. I believe it's still safer than using setuid bits. It's still a backdraw of Linux that it hasn't got more fine-grained access control. Waiting for POSIX.6 compatibility <http://www.xarius.demon.co.uk/software/posix6/>. What is worse, there are shell scripts which are getting called through sudo. Bad enough. Any idea out there?
|
||||
<item>pppd: It runs suid root also. It can be configured by user's .ppprc. There might be some nice buffer overruns in it. The bottom line: secure your slave account as tightly as you can.
|
||||
<item>ssh: Beware that ssh older than 1.2.20 has security holes. What is worse, we made a configuration such when the master account had been compromised, the slave account is also compromised, and wide open to attacks using the two sudoed programs. It is because I've choosen not to have password on the master's secret key to enable automatic setup of the VPN.
|
||||
<item>firewall: With inproperly set firewall rules on one bastion, you open both of the intranets. I recommend using IP masquerading (as setting up incorrect routes is a bit less trivial), and doing hard control on the VPN interfaces.
|
||||
</itemize>
|
||||
|
||||
|
||||
<sect1>About the ppp over ssh VPN technique
|
||||
<p>
|
||||
I developed this technique when there was no usable, standard
|
||||
VPN for Linux. Now this is no longer the case.
|
||||
At the time of writing this, you have the following alternatives:
|
||||
If you want to use standard IPSEC VPN, you can use FreeS/WAN or pipsecd.
|
||||
For PPTP you can use PoPToP (but be aware that PPTP protocol has
|
||||
weaknesses). It is also worth to mention CIPE which is a lightweight
|
||||
alternative for IPSEC.
|
||||
<p>
|
||||
This wide range of alternatives means that the ssh/ppp implementation
|
||||
described in this howto is in the most cases not the best solution.
|
||||
This is due the fact that this implementation is complex to set up
|
||||
and has performance problems because of its tcp based nature.
|
||||
<p>
|
||||
I believe that the ssh/ppp technique is no longer beneficial for
|
||||
building a VPN for non-illegal purposes in most cases, so I have
|
||||
discontinued maintaining this HOWTO.
|
||||
|
||||
|
||||
</article>
|
Loading…
Reference in New Issue