コード例 #1
0
ファイル: vcons-scrollback.c プロジェクト: GNUHurdTR/hurd
/* Scroll back into the history of VCONS.  If TYPE is
   CONS_SCROLL_DELTA_LINES, scroll up or down by VALUE lines.  If TYPE
   is CONS_SCROLL_DELTA_SCREENS, scroll up or down by VALUE multiples
   of a screen height.  If TYPE is CONS_SCROLL_ABSOLUTE_LINE, scroll to
   line VALUE (where 0 is the lowest line).  If TYPE is
   CONS_SCROLL_ABSOLUTE_PERCENTAGE, scroll to the position determined
   by VALUE, where 0 is the bottom and 1 is the top.

   The function returns the number of lines actually scrolled up or
   down.  */
int
cons_vcons_scrollback (vcons_t vcons, cons_scroll_t type, float value)
{
  int ret;

  pthread_mutex_lock (&vcons->lock);
  ret = _cons_vcons_scrollback (vcons, type, value);
  _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
  cons_vcons_update (vcons);
  pthread_mutex_unlock (&vcons->lock);
  return ret;
}
コード例 #2
0
ファイル: vcons-input.c プロジェクト: GNUHurdTR/hurd
/* Enter SIZE bytes from the buffer BUF into the virtual console
   VCONS.  */
error_t
cons_vcons_input (vcons_t vcons, char *buf, size_t size)
{
  pthread_mutex_lock (&vcons->lock);

  _cons_vcons_console_event (vcons, CONS_EVT_KEYPRESS);
  
  if (vcons->scrolling && _cons_jump_down_on_input)
    _cons_vcons_scrollback (vcons, CONS_SCROLL_ABSOLUTE_LINE, 0);

  _cons_vcons_input (vcons, buf, size);

  pthread_mutex_unlock (&vcons->lock);
  return 0;
}
コード例 #3
0
error_t
cons_vcons_move_mouse (vcons_t vcons, mouse_event_t ev)
{
  char event[CONS_MOUSE_EVENT_LENGTH];
  uint32_t report_events;
  
  mutex_lock (&vcons->lock);
  report_events = vcons->display->flags & CONS_FLAGS_TRACK_MOUSE;
  
  switch (ev->mouse_movement)
    {
    case CONS_VCONS_MOUSE_MOVE_REL:
      mousepos_x += ((float) ev->x / _cons_mouse_sens);
      mousepos_y += ((float) ev->y / _cons_mouse_sens);
      break;

    case CONS_VCONS_MOUSE_MOVE_ABS_PERCENT:
      mousepos_x = vcons->state.screen.width * ev->x / 100;
      mousepos_y = vcons->state.screen.height * ev->y / 100;
      
    case CONS_VCONS_MOUSE_MOVE_ABS:
      mousepos_x = ev->x;
      mousepos_y = ev->y;
      break;
    }

  /* Keep the mouse cursor in range of the VC.  */
  if (mousepos_x < 0)
    mousepos_x = 0;
  if (mousepos_y < 0)
    mousepos_y = 0;
  if (mousepos_x >= (float) vcons->state.screen.width)
    mousepos_x = vcons->state.screen.width - 1;
  if (mousepos_y >= (float) vcons->state.screen.height)
    mousepos_y = vcons->state.screen.height - 1;
  
  cons_vcons_set_mousecursor_pos (vcons, (float) mousepos_x, (float) mousepos_y);
  
  /* Report a mouse movement event.  */
  if (ev->x || ev->y)
    _cons_vcons_console_event (vcons, CONS_EVT_MOUSE_MOVE);
  
  /* Report a mouse button event.  */
  if (ev->mouse_button != CONS_VCONS_MOUSE_BUTTON_NO_OP)
    _cons_vcons_console_event (vcons, CONS_EVT_MOUSE_BUTTON);
  
  if (report_events)
    {
      switch (ev->mouse_button)
	{
	case CONS_VCONS_MOUSE_BUTTON_NO_OP:
	  break;

	case CONS_VCONS_MOUSE_BUTTON_PRESSED:
	  /* Make an xterm like event string.  */
	  CONS_MOUSE_EVENT (event, ev->button, (int) mousepos_x + 1, (int) mousepos_y + 1);

	  _cons_vcons_input (vcons, event, CONS_MOUSE_EVENT_LENGTH);
	  /* And send it to the server.  */
	  break;

	case CONS_VCONS_MOUSE_BUTTON_RELEASED:
	  /* Make an xterm like event string.  */
	  CONS_MOUSE_EVENT (event, CONS_MOUSE_RELEASE, (int) mousepos_x + 1, (int) mousepos_y + 1);

	  /* And send it to the server.  */
	  _cons_vcons_input (vcons,  event, CONS_MOUSE_EVENT_LENGTH);
	  break;
	}
    }
  
  mutex_unlock (&vcons->lock);
  return 0;
}
コード例 #4
0
kern_return_t
cons_S_file_changed (cons_notify_t notify, natural_t tickno,
		     file_changed_type_t change,
		     off_t start, off_t end)
{
  error_t err = 0;
  vcons_t vcons = (vcons_t) notify;

  if (!notify || notify->cons)
    return EOPNOTSUPP;

  mutex_lock (&vcons->lock);
  switch (change)
    {
    case FILE_CHANGED_NULL:
      /* Always sent first for sync.  */
      cons_vcons_refresh (vcons);
      break;
    case FILE_CHANGED_WRITE:
      /* File data has been written.  */
      while (vcons->state.changes.written < vcons->display->changes.written)
	{
	  cons_change_t change;
	  
	  if (vcons->display->changes.written - vcons->state.changes.written
	      > vcons->cons->slack)
	    {
	      cons_vcons_refresh (vcons);
	      continue;
	    }
	  change = vcons->state.changes.buffer[vcons->state.changes.written
					       % vcons->state.changes.length];
	  if (vcons->display->changes.written - vcons->state.changes.written
	      > vcons->state.changes.length - 1)
	    {
	      /* While we were reading the entry, the server might
		 have overwritten it.  */
	      cons_vcons_refresh (vcons);
	      continue;
	    }
	  vcons->state.changes.written++;

	  if (change.what.not_matrix)
	    {
	      if (change.what.cursor_pos)
		{
		  uint32_t old_row = vcons->state.cursor.row;
		  uint32_t height = vcons->state.screen.height;
		  uint32_t row;

		  vcons->state.cursor.col = vcons->display->cursor.col;
		  row = vcons->state.cursor.row = vcons->display->cursor.row;

		  if (row + vcons->scrolling < height)
		    {
		      cons_vcons_set_cursor_pos (vcons,
						 vcons->state.cursor.col,
						 row + vcons->scrolling);
		      if (old_row + vcons->scrolling >= height)
			/* The cursor was invisible before.  */
			cons_vcons_set_cursor_status (vcons,
						      vcons->state.cursor.status);
		    }
		  else if (old_row + vcons->scrolling < height)
		    /* The cursor was visible before.  */
		    cons_vcons_set_cursor_status (vcons, CONS_CURSOR_INVISIBLE);

		  _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
		  cons_vcons_update (vcons);
		}
	      if (change.what.cursor_status)
		{
		  vcons->state.cursor.status = vcons->display->cursor.status;
		  cons_vcons_set_cursor_status (vcons,
						vcons->state.cursor.status);
		  cons_vcons_update (vcons);
		}
	      if (change.what.screen_cur_line)
		{
		  uint32_t new_cur_line;

		  new_cur_line = vcons->display->screen.cur_line;

		  if (new_cur_line != vcons->state.screen.cur_line)
		    {
		      off_t size = vcons->state.screen.width
			* vcons->state.screen.lines;
		      off_t vis_start;
		      uint32_t scrolling;
		      off_t start;
		      off_t end;
		      
		      if (new_cur_line > vcons->state.screen.cur_line)
			scrolling = new_cur_line
			  - vcons->state.screen.cur_line;
		      else
			scrolling = UINT32_MAX - vcons->state.screen.cur_line
			  + 1 + new_cur_line;

		      /* If we are scrolling back, defer scrolling
			 until absolutely necessary.  */
		      if (vcons->scrolling)
			{
			  if (_cons_jump_down_on_output)
			    _cons_vcons_scrollback
			      (vcons, CONS_SCROLL_ABSOLUTE_LINE, 0);
			  else
			    {
			      if (vcons->scrolling + scrolling
				  <= vcons->state.screen.scr_lines)
				{
				  vcons->scrolling += scrolling;
				  scrolling = 0;
				}
			      else
				{
				  scrolling -= vcons->state.screen.scr_lines
				    - vcons->scrolling;
				  vcons->scrolling
				    = vcons->state.screen.scr_lines;
				}
			    }
			}

		      if (scrolling)
			{
			  uint32_t cur_disp_line;

			  if (new_cur_line >= vcons->scrolling)
			    cur_disp_line = new_cur_line - vcons->scrolling;
			  else
			    cur_disp_line = (UINT32_MAX - (vcons->scrolling - new_cur_line)) + 1;

			  if (scrolling > vcons->state.screen.height)
			    scrolling = vcons->state.screen.height;
			  if (scrolling < vcons->state.screen.height)
			    cons_vcons_scroll (vcons, scrolling);
			  else
			    cons_vcons_clear (vcons, vcons->state.screen.width
					      * vcons->state.screen.height,
					      0, 0);
			  vis_start = vcons->state.screen.width
			    * (cur_disp_line % vcons->state.screen.lines);
			  start = (((cur_disp_line % vcons->state.screen.lines)
				    + vcons->state.screen.height - scrolling)
				   * vcons->state.screen.width) % size;
			  end = start + scrolling * vcons->state.screen.width - 1;
			  cons_vcons_write (vcons,
					    vcons->state.screen.matrix + start,
					    end < size
					    ? end - start + 1 
					    : size - start,
					    0, vcons->state.screen.height
					    - scrolling);
			  if (end >= size)
			    cons_vcons_write (vcons,
					      vcons->state.screen.matrix,
					      end - size + 1,
					      0, (size - vis_start)
					      / vcons->state.screen.width);
			  _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
			  cons_vcons_update (vcons);
			}
		      vcons->state.screen.cur_line = new_cur_line;
		    }
		}
	      if (change.what.screen_scr_lines)
		{
		  vcons->state.screen.scr_lines
		    = vcons->display->screen.scr_lines;
		  if (vcons->state.screen.scr_lines < vcons->scrolling)
		    assert (!"Implement shrinking scrollback buffer! XXX");
		}
	      if (change.what.bell_audible)
		{
		  while (vcons->state.bell.audible
			 < vcons->display->bell.audible)
		    {
		      if (_cons_audible_bell == BELL_AUDIBLE)
			cons_vcons_beep (vcons);
		      else if (_cons_audible_bell == BELL_VISUAL)
			cons_vcons_flash (vcons);
		      vcons->state.bell.audible++;
		    }
		}
	      if (change.what.bell_visible)
		{
		  while (vcons->state.bell.visible
			 < vcons->display->bell.visible)
		    {
		      if (_cons_visual_bell == BELL_VISUAL)
			cons_vcons_flash (vcons);
		      else if (_cons_visual_bell == BELL_AUDIBLE)
			cons_vcons_beep (vcons);
		      vcons->state.bell.visible++;
		    }
		}
	      if (change.what.flags)
		{
		  uint32_t flags = vcons->display->flags;

		  if ((flags & CONS_FLAGS_SCROLL_LOCK)
		      != (vcons->state.flags & CONS_FLAGS_SCROLL_LOCK))
		    cons_vcons_set_scroll_lock (vcons, flags
						& CONS_FLAGS_SCROLL_LOCK);
		  vcons->state.flags = flags;
		}
	    }
	  else
	    {
	      /* For clipping.  */
	      off_t size = vcons->state.screen.width*vcons->state.screen.lines;
	      off_t rotate;
	      off_t vis_end = vcons->state.screen.height
		* vcons->state.screen.width - 1;
	      off_t end2 = -1;
	      off_t start_rel = 0;    /* start relative to visible start.  */
	      off_t start = change.matrix.start;
	      off_t end = change.matrix.end;

	      if (vcons->scrolling && _cons_jump_down_on_output)
		_cons_vcons_scrollback (vcons, CONS_SCROLL_ABSOLUTE_LINE, 0);

	      if (vcons->state.screen.cur_line >= vcons->scrolling)
		rotate = vcons->state.screen.cur_line - vcons->scrolling;
	      else
		rotate = (UINT32_MAX - (vcons->scrolling - vcons->state.screen.cur_line)) + 1;
	      rotate = vcons->state.screen.width * (rotate % vcons->state.screen.lines);

	      /* Rotate the buffer.  */
	      start -= rotate;
	      if (start < 0)
		start += size;
	      end -= rotate;
	      if (end < 0)
		end += size;
	      
	      /* Find the intersection.  */
	      if (start > vis_end)
		{
		  if (end < start)
		    {
		      start = 0;
		      if (vis_end < end)
			end = vis_end;
		    }
		  else
		    start = -1;
		}
	      else
		{
		  if (end >= start)
		    {
		      if (end > vis_end)
			end = vis_end;
		    }
		  else
		    {
		      end2 = end;
		      end = vis_end;
		    }
		}
	      /* We now have three cases: No intersection if start ==
		 -1, one intersection [start;end] if end2 == -1, and
		 two intersections [start;end] and [0;end2] if end2 !=
		 -1.  However, we still have to undo the buffer
		 rotation.  */
	      if (start != -1)
		{
		  start_rel = start;
		  start += rotate;
		  if (start >= size)
		    start -= size;
		  end += rotate;
		  if (end >= size)
		    end -= size;
		  if (start > end)
		    end += size;
		}
	      if (end2 != -1)
		/* The interval should be [vis_start:end2].  */
		end2 += rotate;
	      
	      if (start != -1)
		{
		  cons_vcons_clear (vcons, end - start + 1,
				    start_rel % vcons->state.screen.width,
				    start_rel / vcons->state.screen.width);
		  cons_vcons_write (vcons, vcons->state.screen.matrix + start,
				    end < size
				    ? end - start + 1
				    : size - start,
				    start_rel % vcons->state.screen.width,
				    start_rel / vcons->state.screen.width);
		  if (end >= size)
		    cons_vcons_write (vcons, vcons->state.screen.matrix,
				      end - size + 1,
				      (size - rotate)
				      % vcons->state.screen.width,
				      (size - rotate)
				      / vcons->state.screen.width);
		  if (end2 != -1)
		    {
		      cons_vcons_clear (vcons, end2 - rotate + 1, 0, 0);
		      cons_vcons_write (vcons,
					vcons->state.screen.matrix + rotate,
					end2 < size
					? end2 - rotate + 1
					: size - rotate,
					0, 0);
		      if (end2 >= size)
			cons_vcons_write (vcons, vcons->state.screen.matrix,
					  end2 - size + 1,
					  (size - rotate)
					  % vcons->state.screen.width,
					  (size - rotate)
					  / vcons->state.screen.width);
		    }
		  _cons_vcons_console_event (vcons, CONS_EVT_OUTPUT);
		  cons_vcons_update (vcons);
		}
	    }
	}
      break;
    case FILE_CHANGED_EXTEND:
      /* File has grown.  */
    case FILE_CHANGED_TRUNCATE:
      /* File has been truncated.  */
    case FILE_CHANGED_META:
      /* Stat information has changed, and none of the previous three
	 apply.  Not sent for changes in node times.  */
    default:
      err = EINVAL;
    };

  mutex_unlock (&vcons->lock);
  return err;
}