Beispiel #1
0
void
resize_terminal(void)
{
	struct interlink_event ev;
	int width, height;

	get_terminal_size(ditrm->out.std, &width, &height);
	set_resize_interlink_event(&ev, width, height);
	itrm_queue_event(ditrm, (char *) &ev, sizeof(ev));
}
Beispiel #2
0
static void send_auth(char *username, char *password) {
	struct mt_packet data;
	unsigned short width = 0;
	unsigned short height = 0;
	char *terminal = getenv("TERM");
	char md5data[100];
	unsigned char md5sum[17];
	int plen;
	md5_state_t state;

#if defined(__linux__) && defined(_POSIX_MEMLOCK_RANGE)
	mlock(md5data, sizeof(md5data));
	mlock(md5sum, sizeof(md5data));
#endif

	/* Concat string of 0 + password + encryptionkey */
	md5data[0] = 0;
	strncpy(md5data + 1, password, 82);
	md5data[83] = '\0';
	memcpy(md5data + 1 + strlen(password), encryptionkey, 16);

	/* Generate md5 sum of md5data with a leading 0 */
	md5_init(&state);
	md5_append(&state, (const md5_byte_t *)md5data, strlen(password) + 17);
	md5_finish(&state, (md5_byte_t *)md5sum + 1);
	md5sum[0] = 0;

	/* Send combined packet to server */
	init_packet(&data, MT_PTYPE_DATA, srcmac, dstmac, sessionkey, outcounter);
	plen = add_control_packet(&data, MT_CPTYPE_PASSWORD, md5sum, 17);
	plen += add_control_packet(&data, MT_CPTYPE_USERNAME, username, strlen(username));
	plen += add_control_packet(&data, MT_CPTYPE_TERM_TYPE, terminal, strlen(terminal));
	
	if (is_a_tty && get_terminal_size(&width, &height) != -1) {
		width = htole16(width);
		height = htole16(height);
		plen += add_control_packet(&data, MT_CPTYPE_TERM_WIDTH, &width, 2);
		plen += add_control_packet(&data, MT_CPTYPE_TERM_HEIGHT, &height, 2);
	}

	outcounter += plen;

	/* TODO: handle result */
	send_udp(&data, 1);
}
Beispiel #3
0
static void sig_winch(int sig) {
	unsigned short width,height;
	struct mt_packet data;
	int plen;

	/* terminal height/width has changed, inform server */
	if (get_terminal_size(&width, &height) != -1) {
		init_packet(&data, MT_PTYPE_DATA, srcmac, dstmac, sessionkey, outcounter);
		width = htole16(width);
		height = htole16(height);
		plen = add_control_packet(&data, MT_CPTYPE_TERM_WIDTH, &width, 2);
		plen += add_control_packet(&data, MT_CPTYPE_TERM_HEIGHT, &height, 2);
		outcounter += plen;

		send_udp(&data, 1);
	}

	/* reinstate signal handler */
	signal(SIGWINCH, sig_winch);
}
Beispiel #4
0
int		pause_screen(t_tetris *game)
{
  char		key[20];

  init_pause(game);
  key[0] = '\0';
  while (my_strcmp(key, game->pause_key) != 0 && get_terminal_size(game) == 0)
    {
      if (my_strcmp(key, game->quit_key) == 0)
	{
	  game->pause = 1;
	  escape_game(game);
	  return (0);
	}
      getstr(key);
    }
  werase(game->pause_screen);
  delwin(game->pause_screen);
  return (0);
}
Beispiel #5
0
int main(int argc, char* argv[])
{
	int is_running = 1;
	int x_terminal_size, y_terminal_size;
        int is_lurking = 0;
        int is_yelling = 0;
        int in_deepsix = 0;
        int sending_im = 0;
        int i;

	/* josh-note:
			These need to be uncommented for the client connection to work. */
/*	int client_id = init_client("Henry");                   create a client. */
/*      init_user_list(client_id);                      init the client size user list. */

	log_init();
	log_writeln(" --------------------------- ");
	log_writeln(" > Starting BlackChat");

        signal(SIGALRM, scroll_ended_handler);

        for(i = 0; i < 26; i ++) {   /* set our message to null */
                memset(yell_messages[i], '\0', MAX_MESSAGE_LENGTH * sizeof(wchar_t)); 
        }

	transcript_buffer   = (wchar_t*)malloc(sizeof(wchar_t)*transcript_buffer_size);
	f_transcript_buffer = (wchar_t*)malloc(sizeof(wchar_t)*f_transcript_buffer_size);
    memset(client_buffer, '\0', sizeof(client_buffer));
	memset(transcript_buffer, '\0', sizeof(transcript_buffer));

	get_terminal_size(&x_terminal_size, &y_terminal_size);
	log_writeln(" > ... detecting current terminal size xy:(%d,%d)", x_terminal_size, y_terminal_size);

	log_writeln(" > ... initializing ncurses screen in raw mode");
	initscr();
//	start_color();
	init_pair(0, COLOR_WHITE,   COLOR_BLACK);
	init_pair(1, COLOR_GREEN,   COLOR_BLACK);
	init_pair(2, COLOR_YELLOW,  COLOR_BLACK);
        init_pair(3, COLOR_CYAN,    COLOR_BLACK);
        init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
	raw();
	keypad(stdscr, TRUE);
	noecho();

	color_set(0, NULL);
	
	log_writeln(" > ... creating transcript and client window");
	transcript_window  				= newwin(TRANSCRIPT_MAX_ROWS,TRANSCRIPT_MAX_COLUMNS,   0,0);
	fullscreen_transcript_window	= newwin(TRANSCRIPT_MAX_ROWS,TRANSCRIPT_MAX_COLUMNS*2, 0,0);
	client_chat_window 				= newwin(MAX_ROWS,MAX_COLUMNS,24,0);
        lurk_win           			= newwin(MAX_ROWS,MAX_COLUMNS,24,0);
        yell_win           			= newwin(23,40,0,0);
        deepsix_win        			= newwin(23,40,0,0);
        im_win						= newwin(TRANSCRIPT_MAX_ROWS,TRANSCRIPT_MAX_COLUMNS,   0,0);
        status_win					= newwin(3,40,21,40);
        info_win					= newwin(3,40,0,40);
   //     box(yell_win, '|', '-');

        set_yell_message(0, L"Hello World");
        set_yell_message(1, L"Yo dog!");
        set_yell_message(2, L"Hey everyone!");
        set_yell_message(3, L"Whats up?");
        set_yell_message(12,L"I agree.");

        wcolor_set(lurk_win,           4, NULL);
        wcolor_set(transcript_window,  3, NULL);
        wcolor_set(client_chat_window, 4, NULL);
        wcolor_set(yell_win,           2, NULL);
        wprintw(lurk_win, "Lurking... Use CTRL-L to unLurk or CTRL-Q to quit.");
	log_writeln(" > ... creating other 9 windows");
	init_other_windows();

	log_writeln(" > ... [beginning transcript]");
	write_to_transcript_window(L"***************************************");
	write_to_transcript_window(L"******** Wecome to BlackChat! *********");
	write_to_transcript_window(L"***************************************");
        
	set_window_user_name(0, L"chris");
	set_window_user_name(1, L"sue");
	set_window_user_name(2, L"dan");
	set_window_user_name(3, L"joe");
	append_text_to_window(0, L"Sup!");
	append_text_to_window(1, L"yo everyone, I'm in love with blackchat!");
	append_text_to_window(2, L"hey, my name is Dan!");
	append_text_to_window(3, L"Hey!?");

	can_deepsix_user(0, 0);
	set_user_status(1, 'L');
	set_user_status(2, 'L');
	
	/* Set our info window text. */
	wprintw(info_win, "       Black Chat  v1.0\n");
	wprintw(info_win, "UI: Henry Stratmann|Client: Josh Hartman\n");
	wprintw(info_win, "Server: Tyler Reid |Protocol: Tim Rhoads\n");
	

	while(is_running) {
		int ch = getch();
/*		wchar_t buf[512];          //get wchar_ts

		sprintf(buf, "key pressed: '%c'  int value: %d\n", ch, ch);
		write_to_transcript_window(buf);
  */                                      //end get wchar_t

            /* Check if were in "Lurk" mode. */
            if(is_lurking) {
                    switch(ch) {
                            case 12: /* lurk-off */
                                    is_lurking = 0;
                                    print_client_chat_buffer();
                                    break;
                            case 17: /* quit */
                                    is_running = 0;
                                    break;
                            default:
                                    wrefresh(lurk_win);
                    }
            }
            /* Check if were in IM mode. */
            else if(sending_im) {
            		/*
            		 TODO: Display list of users (like deepsix) to send IM to.
            		 	All IM's will be displayed on the main transcript with some type of "marker"
            		 	indicating that this was an IM.
            		 */
            		if(ch >= 48 && ch <= 57) {
            				/* josh-note:
            					Have josh send IM based on "ch" */
            		}
            
            
            		/* quit */
                    if(ch == 17) {
                    		is_running = 0;
                    }
                    
                    /* exit IM */
                    sending_im = 0;
                    window_page_up(transcript_window,            &transcript_current_line, TRANSCRIPT_MAX_COLUMNS,   transcript_buffer);
                    window_page_up(fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer);
            }
            /* Check if were in deepsix mode. */
            else if(in_deepsix) {
            		/* kick user */
            		if(ch >= 48 && ch <= 57) {
            				/* josh-note:
            					Have josh make a "kick_user(ch-48)" command. 
            					Also, have josh keep track of who user voted for and display message on transcript as to how user voted
            					and/or if they already voted for the user. */		
            		}
            
            		/* quit */
                    if(ch == 17) {
                    		is_running = 0;
                    }
                    
                    /* exit deepsix */
                    in_deepsix = 0;
                    window_page_up(transcript_window,            &transcript_current_line, TRANSCRIPT_MAX_COLUMNS,   transcript_buffer);
                    window_page_up(fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer);
            }
            /* Check if were yelling. */
            else if(is_yelling) {
                    // redrawwin(yell_win);
                    // wrefresh(yell_win);
                    int index = ch - 97;
        

                    /* Write our comment to our transcript window.  */
                    if(index >= 0 && index < 26) {
                            if( yell_messages[index][0] != '\0' ) {
                                    write_to_transcript_window( yell_messages[index] );
                            }
                    }
                    
                    is_yelling = 0;
                    redrawwin(client_chat_window);
                    wrefresh(client_chat_window);
                    redrawwin(transcript_window);
                    wrefresh(transcript_window);
            } else {
		/* Check what keys we pressed. */
		switch(ch) {
		        /*
			 * Check if we pressed a control key. */
			if(iscntrl(ch)) {
				case 7:  /* CTRL-G */
					gaudy_mode_on = (gaudy_mode_on == 1) ? 0 : 1;
					if(gaudy_mode_on) {
						client_buffer[ client_cursor_position++ ] = 2;
					} else {
						client_buffer[ client_cursor_position++ ] = 3;
					}

					/* Print out updates to the window. */
					print_client_chat_buffer();
					break;

				case 127:/* Backsapce Key (grok hack) */
				case 8:  /* CTRL-H */
					client_buffer[ wcslen(client_buffer)-1 ] = '\0';
					print_client_chat_buffer();
					break;
					
				case 9:  /* CTRL-I   /   TAB */
					if(!sending_im) {
						sending_im = 1;
						draw_im_window();
					}
					break;
					
				case 10: /* CTRL-J and CTRL-M */
		/* UNCOMMENT ME FOR USE WITH SERVER */
					{
						wchar_t *buf = NULL;


						/* If we had gaudy mode on, we need to disable it. */
						if(gaudy_mode_on) {
							client_buffer[ client_cursor_position++ ] = 3;
                                                	client_buffer[ client_cursor_position++ ] = ' ';
							gaudy_mode_on = 0;
						}


						/* Get our buffer togther to write to the transcript window. */
						buf = (wchar_t*)malloc( (wcslen(L"[Client Says]: ")+wcslen(client_buffer)+1) * sizeof(wchar_t) );
						write_to_transcript_window(L"[Client Says]: ");
						write_to_transcript_window(client_buffer);
						
					//	sprintf(buf, "[Client Says]: %ls", client_buffer);
					//	write_to_transcript_window(buf);
					}
					clear_text_from_client_typing_window();
				/*	write_out(client_id);                    enter key is pressed so send a message to the server. */
						    break;

				case 11: /* CTRL-K */
					{
						int i;
						for(i = client_cursor_position+1; i < wcslen(client_buffer); i ++) {
							client_buffer[i] = '\0';
						}
					}
					break;

					    case 12: /* CTRL-L */
							if(!is_lurking) {
							    redrawwin(lurk_win);
							    wrefresh(lurk_win);
							    is_lurking = 1;
							}
						    break;

				case 14: /* CTRL-N */
                                        alarm(5);
					user_is_scrolling = 1;
					transcript_current_line ++;

					window_page_down( transcript_window,
							  &transcript_current_line,
							  TRANSCRIPT_MAX_COLUMNS,
							  transcript_buffer );
							  
					window_page_down( fullscreen_transcript_window,
							  &transcript_current_line,
							  TRANSCRIPT_MAX_COLUMNS*2,
							  f_transcript_buffer );
					break;
				case 16: /* CTRL-P */
                                        alarm(5);
					user_is_scrolling = 1;
					transcript_current_line --;

					window_page_up( transcript_window,
						    	&transcript_current_line,
							TRANSCRIPT_MAX_COLUMNS,
							transcript_buffer );
							
					window_page_up( fullscreen_transcript_window,
							  &transcript_current_line,
							  TRANSCRIPT_MAX_COLUMNS*2,
							  f_transcript_buffer );
					break;
		
				case 17: /* CTRL-Q */ 
					log_writeln(" > ... recived quit signal from client");
					is_running = 0;
					break;
		
				case 20: /* CTRL-T */
					if(transcript_maxed) {
						transcript_maxed = 0;
						window_page_up(transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS, transcript_buffer);
						wclear(fullscreen_transcript_window);
						wrefresh(fullscreen_transcript_window);
					} else {
						transcript_maxed = 1;
						window_page_up(fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer);
						wclear(transcript_window);
						wrefresh(transcript_window);
					}
					break;
		
				case 21: /* CTRL-U */
					client_current_line = 0;
					client_cursor_position = 0;
					memset(client_buffer, '\0', wcslen(client_buffer)+1);	
					print_client_chat_buffer();
					break;

				case 23: /* CTRL-W */
					delete_last_word_in_buffer(client_buffer);
					print_client_chat_buffer();
					break;
                                case 25: /* CTRL-Y */
                                        {
                                            if(!is_yelling)
                                            {
                                                redrawwin(yell_win);
                                                wrefresh(yell_win);
                                                is_yelling = 1;
                                            }
                                        }
                                        break; 
				case 29: /* CTRL-] */
                                        alarm(0);
					user_is_scrolling = 0;
					print_transcript_chat_buffer();
					break;
                                case 30: /* CTRL-6 */
                                        if(!in_deepsix)
                                        {
                                            draw_deepsix_window();
                                            in_deepsix = 1;
                                        }
                                        break;

                                /*
                                 * If we encountered an unkown escape wchar_tcter, break out of here so we don't
                                 * print it. */
                                break;              /* TODO: Fix me! */
			}
#if 0
			/* Scroll the clients typing window down. */
			case KEY_DOWN:
				client_current_line ++;
				if(client_current_line*MAX_COLUMNS > wcslen(client_buffer)) client_current_line --;

					    wclear(client_chat_window);
					    wprintw(client_chat_window, &client_buffer[client_current_line*MAX_COLUMNS]);
					    break;
			/* Scroll the clients typing window up. */
			case KEY_UP:
				client_current_line --;
				if(client_current_line < 0) client_current_line = 0;

					    wclear(client_chat_window);
					    wprintw(client_chat_window, &client_buffer[client_current_line*MAX_COLUMNS]);
					    break;
#endif
			/* Delete the previous chracter. */
			case KEY_BACKSPACE:
				/* Check if were deleting the last wchar_tacter. */
				if( client_cursor_position == wcslen(client_buffer) ) {
					client_buffer[ client_cursor_position-1 ] = '\0';
					client_cursor_position --;
					print_client_chat_buffer();
				} else {
					/* If were here, that means were NOT deleting the last wchar_tacter. */
					int i;
					for(i = client_cursor_position-1; i < wcslen(client_buffer); i ++) {
						client_buffer[i] = client_buffer[i+1];
					}
					client_cursor_position --;
					print_client_chat_buffer();
				}
				break;

			/* If were here, that means we didn't press any "special" keys so that means were
			 * trying to write some generic wchar_tacters to our chat window. */
			default:
				/* Make sure we don't print a control wchar_tacter. */
				if(!iscntrl(ch)) {
					/* Check if were inserting a wchar_tacter before the end of our client
					 * typing buffer. */
					if( client_cursor_position != wcslen(client_buffer) ) {
	
						/* Move all wchar_tacters in front of the cursor up one. */
						int i;
						for(i = wcslen(client_buffer)+1; i > client_cursor_position; i --) {
							client_buffer[i] = client_buffer[i-1];
						}
					}

					/* Add the wchar_tacter to our buffer. */
					client_buffer[ client_cursor_position++ ] = ch;

					/* Print our new/updated buffer. */
					print_client_chat_buffer();
					break;
				}
			}
		}

        	/* Read from the server. */
        	/* josh-note
        			Uncomment this! */
/*      	read_from_server(client_id); */

        	refresh_all_windows(is_lurking);
	}

	log_writeln(" > ... [ending transcript]");
	log_writeln(" > ... freeing resources");
	free_other_windows();
	free(transcript_buffer);

	delwin(transcript_window);
	delwin(fullscreen_transcript_window);
	delwin(client_chat_window);
	delwin(status_win);
	delwin(info_win);
	delwin(im_win);
	delwin(deepsix_win);
	delwin(yell_win);
	endwin();
        
    /* josh-note
    		This should be uncommented to close down the client socket. */
/*  close_client(client_id); */

	log_writeln(" > ... closing client log");
	log_writeln(" > ... bye bye for now!");
	log_close();
	return 0;
}
Beispiel #6
0
int
main(int argc, char *argv[])
{
	int optc;
	int option_differences = 0,
	    option_differences_cumulative = 0,
	    option_help = 0, option_version = 0;
	double interval = 2;
	char *command;
	int command_length = 0;	/* not including final \0 */

	setlocale(LC_ALL, "");
	progname = argv[0];

	while ((optc = getopt_long(argc, argv, "+d::hn:vt", longopts, (int *) 0))
	       != EOF) {
		switch (optc) {
		case 'd':
			option_differences = 1;
			if (optarg)
				option_differences_cumulative = 1;
			break;
		case 'h':
			option_help = 1;
			break;
		case 't':
			show_title = 0;
			break;
		case 'n':
			{
				char *str;
				interval = strtod(optarg, &str);
				if (!*optarg || *str)
					do_usage();
				if(interval < 0.1)
					interval = 0.1;
				if(interval > ~0u/1000000)
					interval = ~0u/1000000;
			}
			break;
		case 'v':
			option_version = 1;
			break;
		default:
			do_usage();
			break;
		}
	}

	if (option_version) {
		fprintf(stderr, "%s\n", VERSION);
		if (!option_help)
			exit(0);
	}

	if (option_help) {
		fprintf(stderr, usage, progname);
		fputs("  -d, --differences[=cumulative]\thighlight changes between updates\n", stderr);
		fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr);
		fputs("  -h, --help\t\t\t\tprint a summary of the options\n", stderr);
		fputs("  -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr);
		fputs("  -v, --version\t\t\t\tprint the version number\n", stderr);
		fputs("  -t, --no-title\t\t\tturns off showing the header\n", stderr);
		exit(0);
	}

	if (optind >= argc)
		do_usage();

	command = strdup(argv[optind++]);
	command_length = strlen(command);
	for (; optind < argc; optind++) {
		char *endp;
		int s = strlen(argv[optind]);
		command = realloc(command, command_length + s + 2);	/* space and \0 */
		endp = command + command_length;
		*endp = ' ';
		memcpy(endp + 1, argv[optind], s);
		command_length += 1 + s;	/* space then string length */
		command[command_length] = '\0';
	}

	get_terminal_size();

	/* Catch keyboard interrupts so we can put tty back in a sane state.  */
	signal(SIGINT, die);
	signal(SIGTERM, die);
	signal(SIGHUP, die);
	signal(SIGWINCH, winch_handler);

	/* Set up tty for curses use.  */
	curses_started = 1;
	initscr();
	nonl();
	noecho();
	cbreak();

	for (;;) {
		time_t t = time(NULL);
		char *ts = ctime(&t);
		int tsl = strlen(ts);
		char *header;
		FILE *p;
		int x, y;
		int oldeolseen = 1;

		if (screen_size_changed) {
			get_terminal_size();
			resizeterm(height, width);
			clear();
			/* redrawwin(stdscr); */
			screen_size_changed = 0;
			first_screen = 1;
		}

		if (show_title) {
			// left justify interval and command,
			// right justify time, clipping all to fit window width
			asprintf(&header, "Every %.1fs: %.*s",
				interval, min(width - 1, command_length), command);
			mvaddstr(0, 0, header);
			if (strlen(header) > (size_t) (width - tsl - 1))
				mvaddstr(0, width - tsl - 4, "...  ");
			mvaddstr(0, width - tsl + 1, ts);
			free(header);
		}

		if (!(p = popen(command, "r"))) {
			perror("popen");
			do_exit(2);
		}

		for (y = show_title; y < height; y++) {
			int eolseen = 0, tabpending = 0;
			for (x = 0; x < width; x++) {
				int c = ' ';
				int attr = 0;

				if (!eolseen) {
					/* if there is a tab pending, just spit spaces until the
					   next stop instead of reading characters */
					if (!tabpending)
						do
							c = getc(p);
						while (c != EOF && !isprint(c)
						       && c != '\n'
						       && c != '\t');
					if (c == '\n')
						if (!oldeolseen && x == 0) {
							x = -1;
							continue;
						} else
							eolseen = 1;
					else if (c == '\t')
						tabpending = 1;
					if (c == EOF || c == '\n' || c == '\t')
						c = ' ';
					if (tabpending && (((x + 1) % 8) == 0))
						tabpending = 0;
				}
				move(y, x);
				if (option_differences) {
					chtype oldch = inch();
					char oldc = oldch & A_CHARTEXT;
					attr = !first_screen
					    && ((char)c != oldc
						||
						(option_differences_cumulative
						 && (oldch & A_ATTRIBUTES)));
				}
				if (attr)
					standout();
				addch(c);
				if (attr)
					standend();
			}
			oldeolseen = eolseen;
		}

		pclose(p);

		first_screen = 0;
		refresh();
		usleep(interval * 1000000);
	}

	endwin();

	return 0;
}
Beispiel #7
0
/* Set xterm-like term window's title. */
void
set_window_title(unsigned char *title)
{
	unsigned char *s;
	int xsize, ysize;
	int j = 0;

#ifndef HAVE_SYS_CYGWIN_H
	/* Check if we're in a xterm-like terminal. */
	if (!is_xterm() && !is_gnuscreen()) return;
#endif

	/* Retrieve terminal dimensions. */
	get_terminal_size(0, &xsize, &ysize);

	/* Check if terminal width is reasonnable. */
	if (xsize < 1 || xsize > 1024) return;

	/* Allocate space for title + 3 ending points + null char. */
	s = mem_alloc(xsize + 3 + 1);
	if (!s) return;

	/* Copy title to s if different from NULL */
	if (title) {
		int i;

		/* We limit title length to terminal width and ignore control
		 * chars if any. Note that in most cases window decoration
		 * reduces printable width, so it's just a precaution. */
		/* Note that this is the right place where to do it, since
		 * potential alternative set_window_title() routines might
		 * want to take different precautions. */
		for (i = 0; title[i] && i < xsize; i++) {
			/* 0x80 .. 0x9f are ISO-8859-* control characters.
			 * In some other encodings they could be used for
			 * legitimate characters, though (ie. in Kamenicky).
			 * We should therefore maybe check for these only
			 * if the terminal is running in an ISO- encoding. */
			if (iscntrl(title[i]) || (title[i] & 0x7f) < 0x20
			    || title[i] == 0x7f)
				continue;

			s[j++] = title[i];
		}

		/* If title is truncated, add "..." */
		if (i == xsize) {
			s[j++] = '.';
			s[j++] = '.';
			s[j++] = '.';
		}
	}
	s[j] = '\0';

	/* Send terminal escape sequence + title string */
	printf("\033]0;%s\a", s);

#if 0
	/* Miciah don't like this so it is disabled because it changes the
	 * default window name. --jonas */
	/* Set the GNU screen window name */
	if (is_gnuscreen())
		printf("\033k%s\033\134", s);
#endif

	fflush(stdout);

	mem_free(s);
}
Beispiel #8
0
int
main(int argc, char *argv[])
{
	int optc;
	int option_differences = 0,
	    option_differences_cumulative = 0,
			option_exec = 0,
			option_beep = 0,
        option_errexit = 0,
	    option_help = 0, option_version = 0;
	double interval = 2;
	char *command;
	char **command_argv;
	int command_length = 0;	/* not including final \0 */
    watch_usec_t next_loop; /* next loop time in us, used for precise time
                               keeping only */
	int pipefd[2];
	int status;
	pid_t child;

	setlocale(LC_ALL, "");
	progname = argv[0];

	while ((optc = getopt_long(argc, argv, "+bed::hn:pvtx", longopts, (int *) 0))
	       != EOF) {
		switch (optc) {
		case 'b':
			option_beep = 1;
			break;
		case 'd':
			option_differences = 1;
			if (optarg)
				option_differences_cumulative = 1;
			break;
        case 'e':
            option_errexit = 1;
            break;
		case 'h':
			option_help = 1;
			break;
		case 't':
			show_title = 0;
			break;
		case 'x':
		  option_exec = 1;
			break;
		case 'n':
			{
				char *str;
				interval = strtod(optarg, &str);
				if (!*optarg || *str)
					do_usage();
				if(interval < 0.1)
					interval = 0.1;
				if(interval > ~0u/1000000)
					interval = ~0u/1000000;
			}
			break;
		case 'p':
			precise_timekeeping = 1;
			break;
		case 'v':
			option_version = 1;
			break;
		default:
			do_usage();
			break;
		}
	}

	if (option_version) {
		fprintf(stderr, "%s\n", VERSION);
		if (!option_help)
			exit(0);
	}

	if (option_help) {
		fprintf(stderr, usage, progname);
		fputs("  -b, --beep\t\t\t\tbeep if the command has a non-zero exit\n", stderr);
		fputs("  -d, --differences[=cumulative]\thighlight changes between updates\n", stderr);
		fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr);
		fputs("  -e, --errexit\t\t\t\texit watch if the command has a non-zero exit\n", stderr);
		fputs("  -h, --help\t\t\t\tprint a summary of the options\n", stderr);
		fputs("  -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr);
        fputs("  -p, --precise\t\t\t\tprecise timing, ignore command run time\n", stderr);
		fputs("  -v, --version\t\t\t\tprint the version number\n", stderr);
		fputs("  -t, --no-title\t\t\tturns off showing the header\n", stderr);
		fputs("  -x, --exec\t\t\t\tpass command to exec instead of sh\n", stderr);
		exit(0);
	}

	if (optind >= argc)
		do_usage();

	command_argv=&(argv[optind]); /* save for later */

	command = strdup(argv[optind++]);
	command_length = strlen(command);
	for (; optind < argc; optind++) {
		char *endp;
		int s = strlen(argv[optind]);
		command = realloc(command, command_length + s + 2);	/* space and \0 */
		endp = command + command_length;
		*endp = ' ';
		memcpy(endp + 1, argv[optind], s);
		command_length += 1 + s;	/* space then string length */
		command[command_length] = '\0';
	}

	get_terminal_size();

	/* Catch keyboard interrupts so we can put tty back in a sane state.  */
	signal(SIGINT, die);
	signal(SIGTERM, die);
	signal(SIGHUP, die);
	signal(SIGWINCH, winch_handler);

	/* Set up tty for curses use.  */
	curses_started = 1;
	initscr();
	nonl();
	noecho();
	cbreak();

	if (precise_timekeeping)
		next_loop = get_time_usec();

	for (;;) {
		time_t t = time(NULL);
		char *ts = ctime(&t);
		int tsl = strlen(ts);
		char *header;
		FILE *p;
		int x, y;
		int oldeolseen = 1;

		if (screen_size_changed) {
			get_terminal_size();
			resizeterm(height, width);
			clear();
			/* redrawwin(stdscr); */
			screen_size_changed = 0;
			first_screen = 1;
		}

		if (show_title) {
			// left justify interval and command,
			// right justify time, clipping all to fit window width
			asprintf(&header, "Every %.1fs: %.*s",
				interval, min(width - 1, command_length), command);
			mvaddstr(0, 0, header);
			if (strlen(header) > (size_t) (width - tsl - 1))
				mvaddstr(0, width - tsl - 4, "...  ");
			mvaddstr(0, width - tsl + 1, ts);
			free(header);
		}

		/* allocate pipes */
		if (pipe(pipefd)<0) {
		  perror("pipe");
			do_exit(7);
	  }

		/* flush stdout and stderr, since we're about to do fd stuff */
		fflush(stdout);
		fflush(stderr);

		/* fork to prepare to run command */
		child=fork();

		if (child<0) { /* fork error */
		  perror("fork");
			do_exit(2);
		} else if (child==0) { /* in child */
			close (pipefd[0]); /* child doesn't need read side of pipe */
			close (1); /* prepare to replace stdout with pipe */
			if (dup2 (pipefd[1], 1)<0) { /* replace stdout with write side of pipe */
			  perror("dup2");
				exit(3);
			}
			dup2(1, 2); /* stderr should default to stdout */

			if (option_exec) { /* pass command to exec instead of system */
			  if (execvp(command_argv[0], command_argv)==-1) {
				  perror("exec");
				  exit(4);
				}
			} else {
		    status=system(command); /* watch manpage promises sh quoting */

			  /* propagate command exit status as child exit status */
			  if (!WIFEXITED(status)) { /* child exits nonzero if command does */
			    exit(1);
			  } else {
			    exit(WEXITSTATUS(status));
		    }
			}

		}

		/* otherwise, we're in parent */
		close(pipefd[1]); /* close write side of pipe */
		if ((p=fdopen(pipefd[0], "r"))==NULL) {
		  perror("fdopen");
			do_exit(5);
		}


		for (y = show_title; y < height; y++) {
			int eolseen = 0, tabpending = 0;
			for (x = 0; x < width; x++) {
				int c = ' ';
				int attr = 0;

				if (!eolseen) {
					/* if there is a tab pending, just spit spaces until the
					   next stop instead of reading characters */
					if (!tabpending)
						do
							c = getc(p);
						while (c != EOF && !isprint(c)
						       && c != '\n'
						       && c != '\t');
					if (c == '\n')
						if (!oldeolseen && x == 0) {
							x = -1;
							continue;
						} else
							eolseen = 1;
					else if (c == '\t')
						tabpending = 1;
					if (c == EOF || c == '\n' || c == '\t')
						c = ' ';
					if (tabpending && (((x + 1) % 8) == 0))
						tabpending = 0;
				}
				move(y, x);
				if (option_differences) {
					chtype oldch = inch();
					unsigned char oldc = oldch & A_CHARTEXT;
					attr = !first_screen
					    && ((char)c != oldc
						||
						(option_differences_cumulative
						 && (oldch & A_ATTRIBUTES)));
				}
				if (attr)
					standout();
				addch(c);
				if (attr)
					standend();
			}
			oldeolseen = eolseen;
		}

		fclose(p);

		/* harvest child process and get status, propagated from command */
		if (waitpid(child, &status, 0)<0) {
		  perror("waitpid");
			do_exit(8);
		};

		/* if child process exited in error, beep if option_beep is set */
		if ((!WIFEXITED(status) || WEXITSTATUS(status))) {
          if (option_beep) beep();
          if (option_errexit) do_exit(8);
		}

		first_screen = 0;
		refresh();
		if (precise_timekeeping) {
			watch_usec_t cur_time = get_time_usec();
			next_loop += USECS_PER_SEC*interval;
			if (cur_time < next_loop)
				usleep(next_loop - cur_time);
		} else
		usleep(interval * 1000000);
	}

	endwin();

	return 0;
}
Beispiel #9
0
int
main(int argc, char *argv[])
{
	int optc;
	int option_differences = 0,
	    option_differences_cumulative = 0,
			option_exec = 0,
			option_beep = 0,
      option_color = 0,
        option_errexit = 0,
	    option_help = 0, option_version = 0;
	double interval = 2;
	char *command;
	wchar_t *wcommand = NULL;
	char **command_argv;
	int command_length = 0;	/* not including final \0 */
	int wcommand_columns = 0;	/* not including final \0 */
	int wcommand_characters = 0; /* not including final \0 */
    watch_usec_t next_loop; /* next loop time in us, used for precise time
                               keeping only */
	int pipefd[2];
	int status;
	pid_t child;

	setlocale(LC_ALL, "");
	progname = argv[0];

	while ((optc = getopt_long(argc, argv, "+bced::hn:pvtx", longopts, (int *) 0))
	       != EOF) {
		switch (optc) {
		case 'b':
			option_beep = 1;
			break;
    case 'c':
      option_color = 1;
      break;
		case 'd':
			option_differences = 1;
			if (optarg)
				option_differences_cumulative = 1;
			break;
        case 'e':
            option_errexit = 1;
            break;
		case 'h':
			option_help = 1;
			break;
		case 't':
			show_title = 0;
			break;
		case 'x':
		  option_exec = 1;
			break;
		case 'n':
			{
				char *str;
				interval = strtod(optarg, &str);
				if (!*optarg || *str)
					do_usage();
				if(interval < 0.1)
					interval = 0.1;
				if(interval > ~0u/1000000)
					interval = ~0u/1000000;
			}
			break;
		case 'p':
			precise_timekeeping = 1;
			break;
		case 'v':
			option_version = 1;
			break;
		default:
			do_usage();
			break;
		}
	}

	if (option_version) {
		fprintf(stderr, "%s\n", VERSION);
		if (!option_help)
			exit(0);
	}

	if (option_help) {
		fprintf(stderr, usage, progname);
		fputs("  -b, --beep\t\t\t\tbeep if the command has a non-zero exit\n", stderr);
		fputs("  -d, --differences[=cumulative]\thighlight changes between updates\n", stderr);
		fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr);
		fputs("  -e, --errexit\t\t\t\texit watch if the command has a non-zero exit\n", stderr);
		fputs("  -h, --help\t\t\t\tprint a summary of the options\n", stderr);
		fputs("  -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr);
        fputs("  -p, --precise\t\t\t\tprecise timing, ignore command run time\n", stderr);
		fputs("  -v, --version\t\t\t\tprint the version number\n", stderr);
		fputs("  -t, --no-title\t\t\tturns off showing the header\n", stderr);
		fputs("  -x, --exec\t\t\t\tpass command to exec instead of sh\n", stderr);
		exit(0);
	}

	if (optind >= argc)
		do_usage();

	command_argv=&(argv[optind]); /* save for later */

	command = strdup(argv[optind++]);
	command_length = strlen(command);
	for (; optind < argc; optind++) {
		char *endp;
		int s = strlen(argv[optind]);
		command = realloc(command, command_length + s + 2);	/* space and \0 */
		endp = command + command_length;
		*endp = ' ';
		memcpy(endp + 1, argv[optind], s);
		command_length += 1 + s;	/* space then string length */
		command[command_length] = '\0';
	}

	// convert to wide for printing purposes
	//mbstowcs(NULL, NULL, 0);
	wcommand_characters = mbstowcs(NULL, command, 0);
	if(wcommand_characters < 0) {
		fprintf(stderr, "Unicode Handling Error\n");
		exit(1);
	}
	wcommand = (wchar_t*)malloc((wcommand_characters+1) * sizeof(wcommand));
	if(wcommand == NULL) {
		fprintf(stderr, "Unicode Handling Error (malloc)\n");
		exit(1);
	}
	mbstowcs(wcommand, command, wcommand_characters+1);
	wcommand_columns = wcswidth(wcommand, -1);



	get_terminal_size();

	/* Catch keyboard interrupts so we can put tty back in a sane state.  */
	signal(SIGINT, die);
	signal(SIGTERM, die);
	signal(SIGHUP, die);
	signal(SIGWINCH, winch_handler);

	/* Set up tty for curses use.  */
	curses_started = 1;
	initscr();
  if (option_color) {
    if (has_colors()) {
      start_color();
      use_default_colors();
      init_ansi_colors();
    } else
      option_color = 0;
  }
	nonl();
	noecho();
	cbreak();

	if (precise_timekeeping)
		next_loop = get_time_usec();

	for (;;) {
		time_t t = time(NULL);
		char *ts = ctime(&t);
		int tsl = strlen(ts);
		char *header;
		FILE *p;
		int x, y;
		int oldeolseen = 1;

		if (screen_size_changed) {
			get_terminal_size();
			resizeterm(height, width);
			clear();
			/* redrawwin(stdscr); */
			screen_size_changed = 0;
			first_screen = 1;
		}

		if (show_title) {
			// left justify interval and command,
			// right justify time, clipping all to fit window width

			int hlen = asprintf(&header, "Every %.1fs: ", interval);

			// the rules:
			//   width < tsl : print nothing
			//   width < tsl + hlen + 1: print ts
			//   width = tsl + hlen + 1: print header, ts
			//   width < tsl + hlen + 4: print header, ..., ts
			//   width < tsl + hlen + wcommand_columns: print header, truncated wcommand, ..., ts
			//   width > "": print header, wcomand, ts
			// this is slightly different from how it used to be
			if(width >= tsl) {
				if(width >= tsl + hlen + 1) {
					mvaddstr(0, 0, header);
					if(width >= tsl + hlen + 2) {
						if(width < tsl + hlen + 4) {
							mvaddstr(0, width - tsl - 4, "...  ");
						}else{
							if(width < tsl + hlen + wcommand_columns) {
								// print truncated
								int avail_columns = width - tsl - hlen;
								int using_columns = wcommand_columns;
								int using_characters = wcommand_characters;
								while(using_columns > avail_columns - 4) {
									using_characters--;
								using_columns = wcswidth(wcommand, using_characters);
								}
								mvaddnwstr(0, hlen, wcommand, using_characters);
								mvaddstr(0, width - tsl - 4, "... ");
							}else{
								mvaddwstr(0, hlen, wcommand);
							}
						}
					}
				}
				mvaddstr(0, width - tsl + 1, ts);
			}

			free(header);
		}

		/* allocate pipes */
		if (pipe(pipefd)<0) {
		  perror("pipe");
			do_exit(7);
	  }

		/* flush stdout and stderr, since we're about to do fd stuff */
		fflush(stdout);
		fflush(stderr);

		/* fork to prepare to run command */
		child=fork();

		if (child<0) { /* fork error */
		  perror("fork");
			do_exit(2);
		} else if (child==0) { /* in child */
			close (pipefd[0]); /* child doesn't need read side of pipe */
			close (1); /* prepare to replace stdout with pipe */
			if (dup2 (pipefd[1], 1)<0) { /* replace stdout with write side of pipe */
			  perror("dup2");
				exit(3);
			}
			dup2(1, 2); /* stderr should default to stdout */

			if (option_exec) { /* pass command to exec instead of system */
			  if (execvp(command_argv[0], command_argv)==-1) {
				  perror("exec");
				  exit(4);
				}
			} else {
		    status=system(command); /* watch manpage promises sh quoting */

			  /* propagate command exit status as child exit status */
			  if (!WIFEXITED(status)) { /* child exits nonzero if command does */
			    exit(1);
			  } else {
			    exit(WEXITSTATUS(status));
		    }
			}

		}

		/* otherwise, we're in parent */
		close(pipefd[1]); /* close write side of pipe */
		if ((p=fdopen(pipefd[0], "r"))==NULL) {
		  perror("fdopen");
			do_exit(5);
		}


		for (y = show_title; y < height; y++) {
			int eolseen = 0, tabpending = 0;
			wint_t carry = WEOF;
			for (x = 0; x < width; x++) {
				wint_t c = L' ';
				int attr = 0;

				if (!eolseen) {
					/* if there is a tab pending, just spit spaces until the
					   next stop instead of reading characters */
					if (!tabpending)
						do {
							if(carry == WEOF) {
								c = my_getwc(p);
							}else{
								c = carry;
								carry = WEOF;
							}
						}while (c != WEOF && !isprint(c) && c<128
						       && wcwidth(c) == 0
						       && c != L'\n'
						       && c != L'\t'
                   && (c != L'\033' || option_color != 1));
          if (c == L'\033' && option_color == 1) {
            x--;
            process_ansi(p);
            continue;
          }
					if (c == L'\n')
						if (!oldeolseen && x == 0) {
							x = -1;
							continue;
						} else
							eolseen = 1;
					else if (c == L'\t')
						tabpending = 1;
					if (x==width-1 && wcwidth(c)==2) {
						y++;
						x = -1; //process this double-width
						carry = c; //character on the next line
						continue; //because it won't fit here
					}
					if (c == WEOF || c == L'\n' || c == L'\t')
						c = L' ';
					if (tabpending && (((x + 1) % 8) == 0))
						tabpending = 0;
				}
				move(y, x);
				if (option_differences) {
						cchar_t oldc;
					in_wch(&oldc);
					attr = !first_screen
					    && ((wchar_t)c != oldc.chars[0]
						||
						(option_differences_cumulative
						 && (oldc.attr & A_ATTRIBUTES)));
				}
				if (attr)
					standout();
				addnwstr((wchar_t*)&c,1);
				if (attr)
					standend();
				if(wcwidth(c) == 0) { x--; }
				if(wcwidth(c) == 2) { x++; }
			}
			oldeolseen = eolseen;
		}

		fclose(p);

		/* harvest child process and get status, propagated from command */
		if (waitpid(child, &status, 0)<0) {
		  perror("waitpid");
			do_exit(8);
		};

		/* if child process exited in error, beep if option_beep is set */
		if ((!WIFEXITED(status) || WEXITSTATUS(status))) {
          if (option_beep) beep();
          if (option_errexit) do_exit(8);
		}

		first_screen = 0;
		refresh();
		if (precise_timekeeping) {
			watch_usec_t cur_time = get_time_usec();
			next_loop += USECS_PER_SEC*interval;
			if (cur_time < next_loop)
				usleep(next_loop - cur_time);
		} else
		usleep(interval * 1000000);
	}

	endwin();

	return 0;
}
Beispiel #10
0
static void fb_gpm_in(void *nic)
{
#ifndef USE_GPM_DX
	static int lx = -1, ly = -1;
#endif
	struct event ev;
	Gpm_Event gev;
	again:
	if (Gpm_GetEvent(&gev) <= 0) {
		unhandle_fb_mouse();
		return;
	}
	/*fprintf(stderr, "%x %x %d %d %d %d\n", gev.type, gev.buttons, gev.dx, gev.dy, gev.wdx, gev.wdy);*/
#ifndef USE_GPM_DX
	if (gev.x != lx || gev.y != ly) {
		mouse_x = (gev.x - 1) * fb_xsize / fb_txt_xsize + fb_xsize / fb_txt_xsize / 2 - 1;
		mouse_y = (gev.y - 1) * fb_ysize / fb_txt_ysize + fb_ysize / fb_txt_ysize / 2 - 1;
		lx = gev.x, ly = gev.y;
	}
#else
	if (gev.dx || gev.dy) {
		if (!((int)gev.type & gpm_smooth)) {
			mouse_x += gev.dx * 8;
			mouse_y += gev.dy * 8;
		}
#ifdef GPM_HAVE_SMOOTH
		else {
			mouse_x += gev.dx;
			mouse_y += gev.dy;
		}
#endif
	}
#endif
	ev.ev = EV_MOUSE;
	if (mouse_x >= fb_xsize) mouse_x = fb_xsize - 1;
	if (mouse_y >= fb_ysize) mouse_y = fb_ysize - 1;
	if (mouse_x < 0) mouse_x = 0;
	if (mouse_y < 0) mouse_y = 0;

	if (!((int)gev.type & gpm_smooth) && (gev.dx || gev.dy)) {
		mouse_x = (mouse_x + 8) / 8 * 8 - 4;
		mouse_y = (mouse_y + 8) / 8 * 8 - 4;
		if (mouse_x >= fb_xsize) mouse_x = fb_xsize - 1;
		if (mouse_y >= fb_ysize) mouse_y = fb_ysize - 1;
		if (mouse_x < 0) mouse_x = 0;
		if (mouse_y < 0) mouse_y = 0;
	}

	ev.x = mouse_x;
	ev.y = mouse_y;
	if (gev.buttons & GPM_B_LEFT) ev.b = B_LEFT;
	else if (gev.buttons & GPM_B_MIDDLE) ev.b = B_MIDDLE;
	else if (gev.buttons & GPM_B_RIGHT) ev.b = B_RIGHT;
	else ev.b = 0;
	if ((int)gev.type & GPM_DOWN) ev.b |= B_DOWN;
	else if ((int)gev.type & GPM_UP) ev.b |= B_UP;
	else if ((int)gev.type & GPM_DRAG) ev.b |= B_DRAG;
	else ev.b |= B_MOVE;

#ifdef HAVE_WDX_WDY
	if ((ev.b & BM_ACT) == B_DRAG || (ev.b & BM_ACT) == B_MOVE) {
		if (gev.wdy < 0) {
			ev.b &= ~BM_BUTT;
			ev.b |= B_WHEELDOWN;
		} else if (gev.wdy > 0) {
			ev.b &= ~BM_BUTT;
			ev.b |= B_WHEELUP;
		}
#if 0
	/* it doesn't work anyway - the exps2 protocol doesn't support it and evdev support in gpm is buggy */
		else if (gev.wdx < 0) {
			ev.b &= ~BM_BUTT;
			ev.b |= B_WHEELRIGHT;
		} else if (gev.wdx > 0) {
			ev.b &= ~BM_BUTT;
			ev.b |= B_WHEELLEFT;
#endif
	}
#endif

#ifndef USE_GPM_DX
	if (fb_msetsize < 0) {
	} else if (fb_msetsize < 10) {
		fb_msetsize++;
	} else if ((ev.b & BM_ACT) == B_MOVE && !(ev.b & BM_BUTT)) {
		fb_mouse_setsize();
		fb_msetsize = -1;
	}
#endif

	if (((ev.b & BM_ACT) == B_MOVE && !(ev.b & BM_BUTT)) || (ev.b & BM_ACT) == B_DRAG) {
		if (can_read(fb_hgpm)) goto again;
	}

	last_mouse_buttons = (int)ev.b;
	if (!current_virtual_device) return;
	if (current_virtual_device->mouse_handler) current_virtual_device->mouse_handler(current_virtual_device, ev.x, ev.y, (int)ev.b);
	redraw_mouse();
}

static int handle_fb_mouse(void)
{
	Gpm_Connect conn;
#ifndef USE_GPM_DX
	int gpm_ver = 0;
	struct winsize ws;
	fb_old_ws_v = 0;
#endif
	fb_hgpm = -1;
#ifndef USE_GPM_DX
	Gpm_GetLibVersion(&gpm_ver);
	fb_msetsize = -1;
	if (gpm_ver >= 11900) {
		int rs;
		EINTRLOOP(rs,ioctl(1, TIOCGWINSZ, &ws));
		if (rs != -1) {
			memcpy(&fb_old_ws, &ws, sizeof(struct winsize));
			fb_old_ws_v = 1;
			ws.ws_row *= 2;
			EINTRLOOP(rs, ioctl(1, TIOCSWINSZ, &ws));
			fb_msetsize = 0;
			memcpy(&fb_new_ws, &ws, sizeof ws);
		}
	}
	get_terminal_size(1, &fb_txt_xsize, &fb_txt_ysize);
#endif
	conn.eventMask = (unsigned short)~0U;
	conn.defaultMask = gpm_smooth;
	conn.minMod = 0;
	conn.maxMod = (unsigned short)~0U;
	if ((fb_hgpm = Gpm_Open(&conn, 0)) < 0) {
		unhandle_fb_mouse();
		return -1;
	}
	set_handlers(fb_hgpm, fb_gpm_in, (void (*)(void *))NULL, (void (*)(void *))NULL, NULL);
#ifdef SIGTSTP
	install_signal_handler(SIGTSTP, (void (*)(void *))sig_tstp, NULL, 0);
#endif
#ifdef SIGCONT
	install_signal_handler(SIGCONT, (void (*)(void *))sig_cont, NULL, 0);
#endif
#ifdef SIGTTIN
	install_signal_handler(SIGTTIN, (void (*)(void *))sig_tstp, NULL, 0);
#endif

	return 0;
}
Beispiel #11
0
/** Construct the struct itrm of this process, make ::ditrm point to it,
 * set up select() handlers, and send the initial interlink packet.
 *
 * The first five parameters are file descriptors that this function
 * saves in submembers of struct itrm, and for which this function may
 * set select() handlers.  Please see the definitions of struct
 * itrm_in and struct itrm_out for further explanations.
 *
 * @param std_in	itrm_in.std: read tty device (or pipe)
 * @param std_out	itrm_out.std: write tty device (or pipe)
 * @param sock_in	itrm_in.sock
 *			- If master: == @a std_out (masterhood flag)
 *			- If slave: read socket from master
 * @param sock_out	itrm_out.sock
 *			- If master: write pipe to same process
 *			- If slave: write socket to master
 * @param ctl_in	itrm_in.ctl: control tty device
 *
 * The remaining three parameters control the initial interlink packet.
 *
 * @param init_string	A string to be passed to the master process.  Need
 *			not be null-terminated.  If @a remote == 0, this is
 *			a URI.  Otherwise, this is a remote command.
 * @param init_len	The length of init_string, in bytes.
 * @param remote	= 0 if asking the master to start a new session
 *			and display it via this process.  Otherwise,
 *			enum ::remote_session_flags.  */
void
handle_trm(int std_in, int std_out, int sock_in, int sock_out, int ctl_in,
	   void *init_string, int init_len, int remote)
{
	struct itrm *itrm;
	struct terminal_info info;
	struct interlink_event_size *size = &info.event.info.size;
	unsigned char *ts;

	memset(&info, 0, sizeof(info));

	get_terminal_size(ctl_in, &size->width, &size->height);
	info.event.ev = EVENT_INIT;
	info.system_env = get_system_env();
	info.length = init_len;

	if (remote) {
		info.session_info = remote;
		info.magic = INTERLINK_REMOTE_MAGIC;
	} else {
		info.session_info = get_cmd_opt_int("base-session");
		info.magic = INTERLINK_NORMAL_MAGIC;
	}

	itrm = mem_calloc(1, sizeof(*itrm));
	if (!itrm) return;

	itrm->in.queue.data = mem_calloc(1, ITRM_IN_QUEUE_SIZE);
	if (!itrm->in.queue.data) {
		mem_free(itrm);
		return;
	}

	ditrm = itrm;
	itrm->in.std = std_in;
	itrm->out.std = std_out;
	itrm->in.sock = sock_in;
	itrm->out.sock = sock_out;
	itrm->in.ctl = ctl_in;
	itrm->timer = TIMER_ID_UNDEF;
	itrm->remote = !!remote;

	/* If the master does not tell which charset it's using in
	 * this terminal, assume it's some ISO 8859.  Because that's
	 * what older versions of ELinks did.  */
	itrm->title_codepage = get_cp_index("ISO-8859-1");

	/* FIXME: Combination altscreen + xwin does not work as it should,
	 * mouse clicks are reportedly partially ignored. */
	if (info.system_env & (ENV_SCREEN | ENV_XWIN))
		itrm->altscreen = 1;

	if (!remote) {
		if (ctl_in >= 0) setraw(itrm, 1);
		send_init_sequence(std_out, itrm->altscreen);
		handle_terminal_resize(ctl_in, resize_terminal);
#ifdef CONFIG_MOUSE
		enable_mouse();
#endif
		handle_itrm_stdin(itrm);
	} else {
		/* elinks -remote may not have a valid stdin if not run from a tty (bug 938) */
		if (std_in >= 0) handle_itrm_stdin(itrm);
	}

	if (sock_in != std_out)
		set_handlers(sock_in, (select_handler_T) in_sock,
			     NULL, (select_handler_T) free_itrm, itrm);

	get_terminal_name(info.name);

	ts = get_cwd();
	if (ts) {
		memcpy(info.cwd, ts, int_min(strlen(ts), MAX_CWD_LEN));
		mem_free(ts);
	}

	itrm_queue_event(itrm, (char *) &info, TERMINAL_INFO_SIZE);
	itrm_queue_event(itrm, (char *) init_string, init_len);
}
Beispiel #12
0
int main(int argc, char* argv[])
{
	int is_running = 1;
	int x_terminal_size, y_terminal_size;

	memset(client_buffer, '\0', sizeof(client_buffer));
	get_terminal_size(&x_terminal_size, &y_terminal_size);
	
	initscr();
	raw();
	keypad(stdscr, TRUE);
	noecho();

	transcript_window  = newwin(23,40,0,0);
	client_chat_window = newwin(MAX_ROWS,MAX_COLUMNS,20,40);

	write_to_transcript_window("Hello!\n");
	write_to_transcript_window("Hey all!\nI love BlackChat, it's so awesome!\n");
	write_to_transcript_window("Press the \'q\' key to quit!");

	while(is_running) {
		int ch = getch();
		switch(ch) {
			case 'q': 
				is_running = 0;
				break;

			/* Scroll the clients typing window down. */
			case KEY_DOWN:
				client_current_line ++;
				if(client_current_line*MAX_COLUMNS > strlen(client_buffer)) client_current_line --;

				wclear(client_chat_window);
				wprintw(client_chat_window, &client_buffer[client_current_line*MAX_COLUMNS]);
				break;
			/* Scroll the clients typing window up. */
			case KEY_UP:
				client_current_line --;
				if(client_current_line < 0) client_current_line = 0;

				wclear(client_chat_window);
				wprintw(client_chat_window, &client_buffer[client_current_line*MAX_COLUMNS]);
				break;
		
			/* Delete the previous chracter. */
			case KEY_BACKSPACE:
				client_buffer[ strlen(client_buffer)-1 ] = '\0';
				print_client_chat_buffer();
				break;

			/* If were here, that means we didn't press any "special" keys so that means were
			 * trying to write some generic characters to our chat window. */
			default:
				/* Store the new char in our buffer. */
				client_buffer[ strlen(client_buffer) ] = ch;
				
				/* Print our new chat buffer. */
				print_client_chat_buffer();
				break;
		}

		wrefresh(transcript_window);
		wrefresh(client_chat_window);
	}

	delwin(transcript_window);
	delwin(client_chat_window);
	endwin();

	return 0;
}