Exemplo n.º 1
0
/* Shutdown pager P and prevent any future paging activity on it.  */
void
pager_shutdown (struct pager *p)
{
  /* Sync and flush pager */
  pager_sync (p, 1);
  pager_flush (p, 1);
  mutex_lock (&p->interlock);
  p->pager_state = SHUTDOWN;
  ports_destroy_right (p);
  mutex_unlock (&p->interlock);
}
Exemplo n.º 2
0
error_t
diskfs_reload_global_state ()
{
  error_t err;

  pokel_flush (&global_pokel);
  pager_flush (diskfs_disk_pager, 1);

  /* libdiskfs is not responsible for inhibiting paging.  */
  err = inhibit_ext2_pager ();
  if (err)
    return err;

  get_hypermetadata ();
  map_hypermetadata ();

  resume_ext2_pager ();

  return 0;
}
Exemplo n.º 3
0
static int completion_try_print( int cols,
				 wchar_t *prefix,
				 int is_quoted,
				 std::vector<comp_t *> &lst )
{
	/*
	  The calculated preferred width of each column
	*/
	int pref_width[PAGER_MAX_COLS];
	/*
	  The calculated minimum width of each column
	*/
	int min_width[PAGER_MAX_COLS];
	/*
	  If the list can be printed with this width, width will contain the width of each column
	*/
	int *width=pref_width;
	/*
	  Set to one if the list should be printed at this width
	*/
	int print=0;
	
	long i, j;
	
	int rows = (int)((lst.size()-1)/cols+1);
	
	int pref_tot_width=0;
	int min_tot_width = 0;
	int res=PAGER_RETRY;
	/*
	  Skip completions on tiny terminals
	*/
	
	if( termsize.ws_col < PAGER_MIN_WIDTH )
		return PAGER_DONE;
	
	memset( pref_width, 0, sizeof(pref_width) );
	memset( min_width, 0, sizeof(min_width) );
	
	/* Calculate how wide the list would be */
	for( j = 0; j < cols; j++ )
	{
		for( i = 0; i<rows; i++ )
		{
			int pref,min;
			comp_t *c;
			if( lst.size() <= j*rows + i )
				continue;

			c = lst.at(j*rows + i );
			pref = c->pref_width;
			min = c->min_width;
			
			if( j != cols-1 )
			{
				pref += 2;
				min += 2;
			}
			min_width[j] = maxi( min_width[j],
					     min );
			pref_width[j] = maxi( pref_width[j],
					      pref );
		}
		min_tot_width += min_width[j];
		pref_tot_width += pref_width[j];
	}
	/*
	  Force fit if one column
	*/
	if( cols == 1)
	{
		if( pref_tot_width > termsize.ws_col )
		{
			pref_width[0] = termsize.ws_col;
		}
		width = pref_width;
		print=1;
	}
	else if( pref_tot_width <= termsize.ws_col )
	{
		/* Terminal is wide enough. Print the list! */
		width = pref_width;
		print=1;
	}
	else
	{
		long next_rows = (lst.size()-1)/(cols-1)+1;
/*		fwprintf( stderr,
  L"cols %d, min_tot %d, term %d, rows=%d, nextrows %d, termrows %d, diff %d\n",
  cols,
  min_tot_width, termsize.ws_col,
  rows, next_rows, termsize.ws_row,
  pref_tot_width-termsize.ws_col );
*/
		if( min_tot_width < termsize.ws_col &&
		    ( ( (rows < termsize.ws_row) && (next_rows >= termsize.ws_row ) ) ||
		      ( pref_tot_width-termsize.ws_col< 4 && cols < 3 ) ) )
		{
			/*
			  Terminal almost wide enough, or squeezing makes the
			  whole list fit on-screen.

			  This part of the code is really important. People hate
			  having to scroll through the completion list. In cases
			  where there are a huge number of completions, it can't
			  be helped, but it is not uncommon for the completions to
			  _almost_ fit on one screen. In those cases, it is almost
			  always desirable to 'squeeze' the completions into a
			  single page. 

			  If we are using N columns and can get everything to
			  fit using squeezing, but everything would also fit
			  using N-1 columns, don't try.
			*/

			int tot_width = min_tot_width;
			width = min_width;

			while( tot_width < termsize.ws_col )
			{
				for( i=0; (i<cols) && ( tot_width < termsize.ws_col ); i++ )
				{
					if( width[i] < pref_width[i] )
					{
						width[i]++;
						tot_width++;
					}
				}
			}
			print=1;
		}
	}

	if( print )
	{
		res=PAGER_DONE;
		if( rows < termsize.ws_row )
		{
			/* List fits on screen. Print it and leave */
			if( is_ca_mode )
			{
				is_ca_mode = 0;
				writembs(exit_ca_mode);
			}
			
			completion_print( cols, width, 0, rows, prefix, is_quoted, lst);
			pager_flush();
		}
		else
		{
			int npos, pos = 0;
			int do_loop = 1;

			/*
			  Enter ca_mode, which means that the terminal
			  content will be restored to the current
			  state on exit.
			*/
			if( enter_ca_mode && exit_ca_mode )
			{
				is_ca_mode=1;
				writembs(enter_ca_mode);
			}
			

			completion_print( cols,
					  width,
					  0,
					  termsize.ws_row-1,
					  prefix,
					  is_quoted,
					  lst);
			/*
			  List does not fit on screen. Print one screenfull and
			  leave a scrollable interface
			*/
			while(do_loop)
			{
				set_color( rgb_color_t::black(), get_color(HIGHLIGHT_PAGER_PROGRESS) );
                wcstring msg = format_string(_(L" %d to %d of %d"), pos, pos+termsize.ws_row-1, rows );
				msg.append(L"   \r" );
								
				writestr(msg.c_str());
				set_color( rgb_color_t::normal(), rgb_color_t::normal() );
				pager_flush();
				int c = readch();

				switch( c )
				{
					case LINE_UP:
					{
						if( pos > 0 )
						{
							pos--;
							writembs(tparm( cursor_address, 0, 0));
							writembs(scroll_reverse);
							completion_print( cols,
									  width,
									  pos,
									  pos+1,
									  prefix,
									  is_quoted,
									  lst );
							writembs( tparm( cursor_address,
									 termsize.ws_row-1, 0) );
							writembs(clr_eol );

						}

						break;
					}

					case LINE_DOWN:
					{
						if( pos <= (rows - termsize.ws_row ) )
						{
							pos++;
							completion_print( cols,
									  width,
									  pos+termsize.ws_row-2,
									  pos+termsize.ws_row-1,
									  prefix,
									  is_quoted,
									  lst );
						}
						break;
					}

					case PAGE_DOWN:
					{

						npos = mini( (int)(rows - termsize.ws_row+1), (int)(pos + termsize.ws_row-1) );
						if( npos != pos )
						{
							pos = npos;
							completion_print( cols,
									  width,
									  pos,
									  pos+termsize.ws_row-1,
									  prefix,
									  is_quoted,
									  lst );
						}
						else
						{
							if( flash_screen )
								writembs( flash_screen );
						}

						break;
					}

					case PAGE_UP:
					{
						npos = maxi( 0,
							     pos - termsize.ws_row+1 );

						if( npos != pos )
						{
							pos = npos;
							completion_print( cols,
									  width,
									  pos,
									  pos+termsize.ws_row-1,
									  prefix,
									  is_quoted,
									  lst );
						}
						else
						{
							if( flash_screen )
								writembs( flash_screen );
						}
						break;
					}

					case R_NULL:
					{
						do_loop=0;
						res=PAGER_RESIZE;
						break;
						
					}
					
					default:
					{
						out_buff.push_back( c );
						do_loop = 0;
						break;
					}					
				}
			}
			writembs(clr_eol);
		}
	}
	return res;
}
Exemplo n.º 4
0
int main( int argc, char **argv )
{
	int i;
	int is_quoted=0;	
	wcstring_list_t comp;
	wchar_t *prefix = 0;

	int mangle_descriptors = 0;
	int result_fd = -1;
	set_main_thread();
    setup_fork_guards();
    
	/*
	  This initialization is made early, so that the other init code
	  can use global_context for memory managment
	*/
	program_name = L"fish_pager";


	wsetlocale( LC_ALL, L"" );

	/*
	  The call signature for fish_pager is a mess. Because we want
	  to be able to upgrade fish without breaking running
	  instances, we need to support all previous
	  modes. Unfortunatly, the two previous ones are a mess. The
	  third one is designed to be extensible, so hopefully it will
	  be the last.
	*/

	if( argc > 1 && argv[1][0] == '-' )
	{
		/*
		  Third mode
		*/
			
		int completion_fd = -1;
		FILE *completion_file;
			
		while( 1 )
		{
			static struct option
				long_options[] =
				{
					{
						"result-fd", required_argument, 0, 'r' 
					}
					,
					{
						"completion-fd", required_argument, 0, 'c' 
					}
					,
					{
						"prefix", required_argument, 0, 'p' 
					}
					,
					{
						"is-quoted", no_argument, 0, 'q' 
					}
					,
					{
						"help", no_argument, 0, 'h' 
					}
					,
					{
						"version", no_argument, 0, 'v' 
					}
					,
					{ 
						0, 0, 0, 0 
					}
				}
			;
		
			int opt_index = 0;
		
			int opt = getopt_long( argc,
					       argv, 
					       GETOPT_STRING,
					       long_options, 
					       &opt_index );
		
			if( opt == -1 )
				break;
		
			switch( opt )
			{
				case 0:
				{
					break;
				}
			
				case 'r':
				{
					result_fd = get_fd( optarg );
					break;
				}
			
				case 'c':
				{
					completion_fd = get_fd( optarg );
					break;
				}

				case 'p':
				{
					prefix = str2wcs(optarg);
					break;
				}

				case 'h':
				{
					print_help( argv[0], 1 );
					exit(0);						
				}

				case 'v':
				{
					debug( 0, L"%ls, version %s\n", program_name, PACKAGE_VERSION );
					exit( 0 );				
				}
					
				case 'q':
				{
					is_quoted = 1;
				}
			
			}
		}

		if( completion_fd == -1 || result_fd == -1 )
		{
			debug( 0, _(L"Unspecified file descriptors") );
			exit( 1 );
		}
			

		if( (completion_file = fdopen( completion_fd, "r" ) ) )
		{
			read_array( completion_file, comp );
			fclose( completion_file );
		}
		else
		{
			debug( 0, _(L"Could not read completions") );
			wperror( L"fdopen" );
			exit( 1 );
		}

		if( !prefix )
		{
			prefix = wcsdup( L"" );
		}
			
			
	}
	else
	{
		/*
		  Second or first mode. These suck, but we need to support
		  them for backwards compatibility. At least for some
		  time.

		  Third mode was implemented in January 2007, and previous
		  modes should be considered deprecated from that point
		  forward. A reasonable time frame for removal of the code
		  below has yet to be determined.
		*/
			
		if( argc < 3 )
		{
			print_help( argv[0], 1 );
			exit( 0 );
		}
		else
		{
			mangle_descriptors = 1;
			
			prefix = str2wcs( argv[2] );
			is_quoted = strcmp( "1", argv[1] )==0;
			
			if( argc > 3 )
			{
				/*
				  First mode
				*/
				for( i=3; i<argc; i++ )
				{
					wcstring wcs = str2wcstring( argv[i] );
                    comp.push_back(wcs);
				}
			}
			else
			{
				/*
				  Second mode
				*/
				read_array( stdin, comp );
			}
		}
			
	}
		
//		debug( 3, L"prefix is '%ls'", prefix );
		
	init( mangle_descriptors, result_fd );

	mangle_descriptions( comp );

	if( wcscmp( prefix, L"-" ) == 0 )
		join_completions( comp );

	std::vector<comp_t *> completions = mangle_completions( comp, prefix );

	/**
	   Try to print the completions. Start by trying to print the
	   list in PAGER_MAX_COLS columns, if the completions won't
	   fit, reduce the number of columns by one. Printing a single
	   column never fails.
	*/
	for( i = PAGER_MAX_COLS; i>0; i-- )
	{
		switch( completion_try_print( i, prefix, is_quoted, completions ) )
		{

			case PAGER_RETRY:
				break;

			case PAGER_DONE:
				i=0;
				break;

			case PAGER_RESIZE:
				/*
				  This means we got a resize event, so we start
				  over from the beginning. Since it the screen got
				  bigger, we might be able to fit all completions
				  on-screen.
				*/
				i=PAGER_MAX_COLS+1;
				break;

		}		
	}
	
	free(prefix );

	fwprintf( out_file, L"%ls", out_buff.c_str() );
	if( is_ca_mode )
	{
		writembs(exit_ca_mode);
		pager_flush();
	}
	destroy();

}