Programowanie z ncurses (index)
W katalogu domowym utworzyć podkatalog skarbiec. Utworzyć w nim pliki Makefile i skarbiec.c postaci:
/* * skarbiec.c */ #include <unistd.h> /* sleep() */ #include <string.h> /* strcmp() */ #include <stdlib.h> #include <curses.h> #define MAXLINE 80 int main(void) { int c, i; int ymax, xmax; char tajne[]= "sezam"; /* haslo do skarbca */ char napis[MAXLINE]; /* haslo podane przez usera */ int koniec= FALSE; /* sterowanie petla do-while */ WINDOW *win; initscr(); /* mozna sprawdzic */ crmode(); /* zmiana trybu pracy */ getmaxyx(stdscr, ymax, xmax); if ((win= subwin(stdscr, 3, 60, ymax/3, (xmax-60)/2)) == NULL) { endwin(); fprintf(stderr,"Error: subwin()\n"); exit(1); } do { /* sprawdzanie hasla */ box(win, ACS_VLINE, ACS_HLINE); /* ramka na okno */ mvwaddstr(win, 1, 1, "Klucz do skarbca: "); wrefresh(win); noecho(); i= 0; while ((c= getch()) != '\n' && (i < MAXLINE)) { napis[i]= c; ++i; waddch(win, '*'); wrefresh(win); } echo(); napis[i]= '\0'; if (strcmp(napis,tajne) == 0) { koniec= TRUE; } else { wclear(win); mvwprintw(win, 1, 1, "Klucz nieprawidlowy!"); box(win, ACS_VLINE, ACS_HLINE); /* ramka na okno */ wrefresh(win); sleep(2); } wclear(win); } while (koniec == FALSE); /* powtarzaj dopoki to jest prawda */ mvwprintw(win, 1, 1, "Podano dobry klucz: %s\n", napis); box(win, ACS_VLINE, ACS_HLINE); /* ramka na okno */ wrefresh(win); sleep(2); delwin(win); endwin(); return 0; }
Skompilować i uruchomić program.
W katalogu domowym utworzyć podkatalog samolot. Utworzyć w nim pliki Makefile i samolot.c postaci:
/* * samolot.c (subwin) */ #include <unistd.h> /* sleep() */ #include <stdlib.h> /* exit() */ #include <curses.h> #define ROZMIAR 10 #define KROK 7 int main(void) { int i; int xmax, ymax; WINDOW *win; initscr(); /* mozna sprawdzic */ bkgd('.'); refresh(); if ((win= subwin(stdscr,ROZMIAR,ROZMIAR,0,0)) == NULL) { endwin(); fprintf(stderr,"Error: subwin()\n"); exit(1); } wbkgd(win, ' '); /* trzeba zaslonic kropki z stdscr */ wprintw(win, "\n SAMOLOT\n"); box(win,0,0); wrefresh(win); sleep(1); getmaxyx(stdscr,ymax,xmax); i= 0; while (i < (xmax-ROZMIAR)) { mvwin(win, (ymax-ROZMIAR)/2, i); refresh(); /* odswiezamy tylko stdscr! */ sleep(1); i+= KROK; } delwin(win); endwin(); return 0; }
Skompilować i uruchomić program.
W katalogu domowym utworzyć podkatalog samolot2. Utworzyć w nim pliki Makefile i samolot2.c postaci:
/* * samolot2.c (newwin) */ #include <unistd.h> /* sleep() */ #include <stdlib.h> /* exit() */ #include <curses.h> #define ROZMIAR 15 #define KROK 10 int main(void) { int i; int xmax, ymax; WINDOW *win; initscr(); /* mozna sprawdzic */ bkgd('.'); refresh(); if ((win= newwin(ROZMIAR,ROZMIAR,1,1)) == NULL) { endwin(); fprintf(stderr,"Error: newwin()\n"); exit(1); } wbkgd(win, ' '); mvwprintw(win,1,1, " SAMOLOT"); box(win,0,0); wrefresh(win); sleep(1); getmaxyx(stdscr,ymax,xmax); i= 0; while (i < (xmax-ROZMIAR)) { mvwin(win, (ymax-ROZMIAR)/2, i); clear(); /* trzeba wymazac poprzedni obrazek okna */ refresh(); wrefresh(win); /* bez tego nie narysuje win */ sleep(1); i+= KROK; } delwin(win); endwin(); return 0; }
Skompilować i uruchomić program.
W katalogu domowym utworzyć podkatalog samolot3. Utworzyć w nim pliki Makefile i samolot3.c postaci:
/* * samolot3.c (sterowanie kursorami) */ #include <stdlib.h> /* exit() */ #include <curses.h> #define YSIZE 5 /* wysokosc okna */ #define XSIZE 9 /* szerokosc okna */ int main(void) { int ch; int ymax, xmax; int ystart, xstart; WINDOW *win; initscr(); /* mozna sprawdzic */ cbreak(); keypad(stdscr, TRUE); getmaxyx(stdscr,ymax,xmax); ystart= (ymax - YSIZE) / 2; xstart= (xmax - XSIZE) / 2; bkgd('.'); printw("Press F1 to exit"); refresh(); if ((win= subwin(stdscr,YSIZE,XSIZE,ystart,xstart)) == NULL) { endwin(); /* najpierw konczymy curses */ fprintf(stderr,"Error: subwin()\n"); exit(1); } wbkgd(win, ' '); /* trzeba zaslonic kropki z stdscr */ wprintw(win, "\n SAMOLOT\n"); box(win,0,0); wrefresh(win); while ((ch = getch()) != KEY_F(1)) { if (ch == KEY_LEFT) { mvwin(win, ystart, --xstart); } else if (ch == KEY_RIGHT) { mvwin(win, ystart, ++xstart); } else if (ch == KEY_UP) { mvwin(win, --ystart, xstart); } else if (ch == KEY_DOWN) { mvwin(win, ++ystart, xstart); } refresh(); /* odswiezamy tylko stdscr! */ } delwin(win); endwin(); return (0); }
Skompilować i uruchomić program. Poprawić program, aby podokno nie wychodziło poza krawędzie ekranu.
W katalogu domowym utworzyć podkatalog win_border. Utworzyć w nim pliki Makefile i win_border.c postaci:
/* * win_border.c * * Program z HOWTO zmodyfikowany. */ #include <ncurses.h> WINDOW *create_win(int height, int width, int starty, int startx); void destroy_win(WINDOW *local_win); int main(void) { WINDOW *win; int xmax, ymax; int startx, starty, width, height; int ch; initscr(); cbreak(); keypad(stdscr, TRUE); getmaxyx(stdscr, ymax, xmax); height = 3; width = 10; starty = (ymax - height) / 2; /* Obliczmy polozenie okna */ startx = (xmax - width) / 2; printw("Press F1 to exit"); refresh(); win = create_win(height, width, starty, startx); while ((ch = getch()) != KEY_F(1)) { if (ch == KEY_LEFT) { destroy_win(win); win = create_win(height, width, starty, --startx); } else if (ch == KEY_RIGHT) { destroy_win(win); win = create_win(height, width, starty, ++startx); } else if (ch == KEY_UP) { destroy_win(win); win = create_win(height, width, --starty, startx); } else if (ch == KEY_DOWN) { destroy_win(win); win = create_win(height, width, ++starty, startx); } } endwin(); return 0; } WINDOW *create_win(int height, int width, int starty, int startx) { WINDOW *local_win; local_win = newwin(height, width, starty, startx); box(local_win,0,0); wrefresh(local_win); return local_win; } void destroy_win(WINDOW *local_win) { /* box(local_win, ' ', ' '); to nie dziala, bo zostaja narozniki */ /* tutaj recznie wymazuje ramki i nie trzeba robic refresh() dla stdscr */ wborder(local_win,' ',' ',' ',' ',' ',' ',' ',' '); wrefresh(local_win); delwin(local_win); return; }
Skompilować i uruchomić program. Poprawić program, aby podokno nie wychodziło poza krawędzie ekranu.
// Podokna, y i x wg ekranu WINDOW *subwin(WINDOW *orig, int nlines, int ncols, int begin_y, int begin_x); // jw, ale y i x wg okna nadrzędnego orig WINDOW *derwin(WINDOW *orig, int nlines, int ncols, int begin_y, int begin_x); // Nowe okna WINDOW *newwin(int nlines, int ncols, int begin_y, int begin_x); // duplikat istniejącego okna WINDOW *dupwin(WINDOW *win); delwin(win);
Okna zdefiniowane przez programistę mogą być dwojakiego rodzaju: podokna [subwin(), derwin() - współdzielą pamięć z oknem pierwotnym] lub okna niezależne [newwin(), dupwin()]. Dokumentacja biblioteki zaleca stosować okna niezależne.
Funkcja newwin() alokuje pamięć dla struktury związanej z nowym oknem, inicjalizuje dane związane z oknem, takie jak rozmiar i położenie początkowe. Funkcja zwraca wskaźnik do struktury WINDOW, który może być przekazany do funkcji typu wprintw() itp. Okno jest usuwane przez funkcję delwin(), która zwalnia pamięć związaną ze strukturą okna.