Changeset 2402
- Timestamp:
- Jun 15, 2008, 3:11:19 PM (14 years ago)
- Location:
- neercs/trunk/src
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
neercs/trunk/src/Makefile.am
r2362 r2402 2 2 bin_PROGRAMS = neercs 3 3 4 neercs_SOURCES = main.c neercs.hterm.c effects.c wm.c4 neercs_SOURCES = neercs.h main.c screens.c term.c effects.c wm.c 5 5 neercs_CFLAGS = @CACA_CFLAGS@ 6 6 neercs_LDADD = @CACA_LIBS@ @UTIL_LIBS@ -
neercs/trunk/src/main.c
r2401 r2402 36 36 37 37 #include "neercs.h" 38 39 40 static int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid);41 38 42 39 int main(int argc, char **argv) … … 264 261 return 0; 265 262 } 266 267 static int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid)268 {269 char **argv;270 int fd;271 pid_t pid;272 273 pid = forkpty(&fd, NULL, NULL, NULL);274 if(pid < 0)275 {276 fprintf(stderr, "forkpty() error\n");277 return -1;278 }279 else if(pid == 0)280 {281 set_tty_size(0, w, h);282 putenv("CACA_DRIVER=slang");283 putenv("TERM=xterm");284 argv = malloc(2 * sizeof(char *));285 if(!argv)286 {287 fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);288 return -1;289 }290 argv[0] = cmd;291 argv[1] = NULL;292 execvp(cmd, argv);293 fprintf(stderr, "execvp() error\n");294 return -1;295 }296 297 *cpid = pid;298 299 fcntl(fd, F_SETFL, O_NDELAY);300 return fd;301 #if 0302 fprintf(stderr, "forkpty() not available\n");303 return -1;304 #endif305 }306 307 int set_tty_size(int fd, unsigned int w, unsigned int h)308 {309 struct winsize ws;310 311 memset(&ws, 0, sizeof(ws));312 ws.ws_row = h;313 ws.ws_col = w;314 ioctl(fd, TIOCSWINSZ, (char *)&ws);315 316 return 0;317 }318 319 320 321 int update_terms(struct screen_list* screen_list)322 {323 int i, refresh = 0;324 for(i = 0; i < screen_list->count; i++)325 {326 if(screen_list->screen[i]->total)327 {328 unsigned long int bytes;329 330 bytes = import_term(screen_list,331 screen_list->screen[i],332 screen_list->screen[i]->buf,333 screen_list->screen[i]->total);334 335 if(bytes > 0)336 {337 screen_list->screen[i]->total -= bytes;338 memmove(screen_list->screen[i]->buf,339 screen_list->screen[i]->buf + bytes,340 screen_list->screen[i]->total);341 refresh = 1;342 }343 }344 }345 return refresh;346 }347 348 349 350 351 int update_screens_contents(struct screen_list* screen_list,352 int *pty, int *prevpty)353 {354 int i, refresh = 0;355 int maxfd = 0;356 struct timeval tv;357 fd_set fdset;358 int ret;359 360 /* Read data, if any */361 FD_ZERO(&fdset);362 for(i = 0; i < screen_list->count; i++)363 {364 if(screen_list->screen[i]->fd >= 0)365 FD_SET(screen_list->screen[i]->fd, &fdset);366 if(screen_list->screen[i]->fd > maxfd)367 maxfd = screen_list->screen[i]->fd;368 }369 tv.tv_sec = 0;370 tv.tv_usec = 50000;371 ret = select(maxfd + 1, &fdset, NULL, NULL, &tv);372 373 if(ret < 0)374 {375 if(errno == EINTR)376 ; /* We probably got a SIGWINCH, ignore it */377 else378 {379 for(i = 0; i < screen_list->count; i++)380 if(screen_list->screen[i]->total)381 break;382 if(i == screen_list->count)383 return 0;384 }385 }386 else if(ret)387 {388 389 for(i = 0; i < screen_list->count; i++)390 {391 /* FIXME: try a new strategy: read all filedescriptors until392 * each of them starved at least once. */393 394 if(screen_list->screen[i]->fd < 0 ||395 !FD_ISSET(screen_list->screen[i]->fd, &fdset))396 continue;397 398 for(;;)399 {400 ssize_t nr;401 402 screen_list->screen[i]->buf =403 realloc(screen_list->screen[i]->buf,404 screen_list->screen[i]->total + 1024);405 nr = read(screen_list->screen[i]->fd,406 screen_list->screen[i]->buf +407 screen_list->screen[i]->total, 1024);408 409 if(nr > 0)410 {411 screen_list->screen[i]->total += nr;412 continue;413 }414 415 if(nr == 0 || errno != EWOULDBLOCK) {416 close(screen_list->screen[i]->fd);417 screen_list->screen[i]->fd = -1;418 destroy_screen(screen_list->screen[i]);419 remove_screen(screen_list, i, 0);420 if(i < (*prevpty)) (*prevpty)--;421 if(i == *pty)422 {423 *pty = *prevpty;424 *prevpty = 0;425 }426 if(i < (*pty)) (*pty)--;427 refresh = 1;428 }429 430 break;431 }432 }433 }434 return refresh;435 }436 437 void refresh_screens(cucul_canvas_t *cv,438 caca_display_t *dp,439 struct screen_list *screen_list,440 int pty)441 {442 int i;443 444 screen_list->width = cucul_get_canvas_width(cv);445 screen_list->height = cucul_get_canvas_height(cv) - (screen_list->mini*6);446 447 update_windows_props(cv, screen_list, pty);448 449 if(screen_list->screen[pty]->title)450 caca_set_display_title(dp, screen_list->screen[pty]->title);451 else452 caca_set_display_title(dp, PACKAGE_STRING);453 454 cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_DEFAULT);455 cucul_clear_canvas(cv);456 cucul_set_color_ansi(cv, CUCUL_LIGHTRED, CUCUL_BLACK);457 458 for(i = screen_list->count - 1; i >=0; i--)459 {460 if(i!=pty)461 {462 cucul_blit(cv,463 screen_list->screen[i]->x,464 screen_list->screen[i]->y,465 screen_list->screen[i]->cv, NULL);466 cucul_draw_cp437_box(cv,467 screen_list->screen[i]->x - 1,468 screen_list->screen[i]->y - 1,469 screen_list->screen[i]->w + 2,470 screen_list->screen[i]->h + 2);471 if(screen_list->screen[i]->title)472 cucul_printf(cv,473 screen_list->screen[i]->x,474 screen_list->screen[i]->y - 1,475 " %.*s ",476 screen_list->screen[i]->w - 3,477 screen_list->screen[i]->title);478 }479 }480 481 cucul_blit(cv,482 screen_list->screen[pty]->x,483 screen_list->screen[pty]->y,484 screen_list->screen[pty]->cv, NULL);485 486 if(screen_list->screen[pty]->bell)487 {488 cucul_set_color_ansi(cv, CUCUL_RED, CUCUL_BLACK);489 screen_list->screen[pty]->bell = 0;490 screen_list->in_bell--;491 }492 else493 {494 cucul_set_color_ansi(cv, CUCUL_LIGHTGREEN, CUCUL_BLACK);495 }496 497 cucul_draw_cp437_box(cv,498 screen_list->screen[pty]->x - 1,499 screen_list->screen[pty]->y - 1,500 screen_list->screen[pty]->w + 2,501 screen_list->screen[pty]->h + 2);502 503 if(screen_list->screen[pty]->title)504 {505 cucul_printf(cv,506 screen_list->screen[pty]->x,507 screen_list->screen[pty]->y - 1,508 " %.*s ",509 screen_list->screen[pty]->w - 3,510 screen_list->screen[pty]->title);511 }512 513 cucul_gotoxy(cv,514 screen_list->screen[pty]->x +515 cucul_get_cursor_x(screen_list->screen[pty]->cv),516 screen_list->screen[pty]->y +517 cucul_get_cursor_y(screen_list->screen[pty]->cv));518 519 520 if(screen_list->mini)521 {522 draw_thumbnails(cv, screen_list, pty);523 }524 if(screen_list->status)525 {526 draw_status(cv, screen_list, pty);527 }528 if(screen_list->help)529 {530 draw_help(cv, screen_list, pty);531 }532 533 caca_refresh_display(dp);534 }535 536 537 538 struct screen* create_screen(int w, int h, char *command)539 {540 struct screen *s = (struct screen*) malloc(sizeof(struct screen));541 542 s->cv = cucul_create_canvas(w, h);543 cucul_set_color_ansi(s->cv, CUCUL_BLACK, CUCUL_BLACK);544 cucul_clear_canvas(s->cv);545 s->init = 0;546 547 s->buf = NULL;548 s->title = NULL;549 s->total = 0;550 s->w = w+1;551 s->h = h+1;552 s->bell = 0;553 554 s->fd = create_pty(command, w, h, &s->pid);555 556 if(s->fd < 0)557 {558 cucul_free_canvas(s->cv);559 free(s);560 return NULL;561 }562 return s;563 }564 565 int destroy_screen(struct screen *s)566 {567 if(s->fd>0)568 close(s->fd);569 if(s->buf)570 free(s->buf);571 if(s->title)572 free(s->title);573 s->buf = NULL;574 if(s->cv)575 cucul_free_canvas(s->cv);576 s->cv = NULL;577 if(s)578 free(s);579 s = NULL;580 return 1;581 }582 583 int add_screen(struct screen_list *list, struct screen *s)584 {585 if(list == NULL || s == NULL) return -1;586 587 else588 {589 list->screen = (struct screen**) realloc(list->screen,590 sizeof(sizeof(struct screen*))591 * (list->count+1));592 list->screen[list->count] = s;593 list->count++;594 }595 596 return list->count-1;597 }598 599 int remove_screen(struct screen_list *list, int n, int please_kill)600 {601 if(n>list->count) return -1;602 603 if(please_kill)604 {605 int status = 0;606 int ret = 0;607 /* FIXME */608 close(list->screen[n]->fd);609 list->screen[n]->fd = -1;610 kill(list->screen[n]->pid, SIGINT);611 ret = waitpid(list->screen[n]->pid, &status,612 WNOHANG|WUNTRACED|WCONTINUED);613 if(!ret)614 kill(list->screen[n]->pid, SIGQUIT);615 ret = waitpid(list->screen[n]->pid, &status,616 WNOHANG|WUNTRACED|WCONTINUED);617 if(!ret)618 kill(list->screen[n]->pid, SIGABRT);619 ret = waitpid(list->screen[n]->pid, &status,620 WNOHANG|WUNTRACED|WCONTINUED);621 if(!ret)622 kill(list->screen[n]->pid, SIGKILL);623 624 }625 626 memmove(&list->screen[n],627 &list->screen[n+1],628 sizeof(struct screen*)*(list->count-(n+1)));629 630 list->screen = (struct screen**) realloc(list->screen,631 sizeof(sizeof(struct screen*))632 * (list->count));633 634 list->count--;635 return 1;636 }637 -
neercs/trunk/src/neercs.h
r2401 r2402 65 65 66 66 67 int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid); 67 68 68 69 long int import_term(struct screen_list *screen_list, struct screen *sc, void const *data, unsigned int size); -
neercs/trunk/src/term.c
r2396 r2402 18 18 #include <stdio.h> 19 19 #include <string.h> 20 #include <pty.h> 21 #include <unistd.h> 22 #include <fcntl.h> 23 20 24 #include <cucul.h> 21 25 #include <caca.h> … … 535 539 } 536 540 541 int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid) 542 { 543 char **argv; 544 int fd; 545 pid_t pid; 546 547 pid = forkpty(&fd, NULL, NULL, NULL); 548 if(pid < 0) 549 { 550 fprintf(stderr, "forkpty() error\n"); 551 return -1; 552 } 553 else if(pid == 0) 554 { 555 set_tty_size(0, w, h); 556 putenv("CACA_DRIVER=slang"); 557 putenv("TERM=xterm"); 558 argv = malloc(2 * sizeof(char *)); 559 if(!argv) 560 { 561 fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__); 562 return -1; 563 } 564 argv[0] = cmd; 565 argv[1] = NULL; 566 execvp(cmd, argv); 567 fprintf(stderr, "execvp() error\n"); 568 return -1; 569 } 570 571 *cpid = pid; 572 573 fcntl(fd, F_SETFL, O_NDELAY); 574 return fd; 575 } 576 577 int set_tty_size(int fd, unsigned int w, unsigned int h) 578 { 579 struct winsize ws; 580 581 memset(&ws, 0, sizeof(ws)); 582 ws.ws_row = h; 583 ws.ws_col = w; 584 ioctl(fd, TIOCSWINSZ, (char *)&ws); 585 586 return 0; 587 } 588 589 590 591 int update_terms(struct screen_list* screen_list) 592 { 593 int i, refresh = 0; 594 for(i = 0; i < screen_list->count; i++) 595 { 596 if(screen_list->screen[i]->total) 597 { 598 unsigned long int bytes; 599 600 bytes = import_term(screen_list, 601 screen_list->screen[i], 602 screen_list->screen[i]->buf, 603 screen_list->screen[i]->total); 604 605 if(bytes > 0) 606 { 607 screen_list->screen[i]->total -= bytes; 608 memmove(screen_list->screen[i]->buf, 609 screen_list->screen[i]->buf + bytes, 610 screen_list->screen[i]->total); 611 refresh = 1; 612 } 613 } 614 } 615 return refresh; 616 } 617
Note: See TracChangeset
for help on using the changeset viewer.