Пример #1
0
/* Add a new watch to watch-descriptor WD watching FILENAME and using
   IMASK and CALLBACK.  Return a cons (DESCRIPTOR . ID) uniquely
   identifying the new watch.  */
static Lisp_Object
add_watch (int wd, Lisp_Object filename,
	   uint32_t imask, Lisp_Object callback)
{
  Lisp_Object descriptor = INTEGER_TO_CONS (wd);
  Lisp_Object tail = assoc_no_quit (descriptor, watch_list);
  Lisp_Object watch, watch_id;
  Lisp_Object mask = INTEGER_TO_CONS (imask);

  EMACS_INT id = 0;
  if (NILP (tail))
    {
      tail = list1 (descriptor);
      watch_list = Fcons (tail, watch_list);
    }
  else
    {
      /* Assign a watch ID that is not already in use, by looking
	 for a gap in the existing sorted list.  */
      for (; ! NILP (XCDR (tail)); tail = XCDR (tail), id++)
	if (!EQ (XCAR (XCAR (XCDR (tail))), make_number (id)))
	  break;
      if (MOST_POSITIVE_FIXNUM < id)
	emacs_abort ();
    }

  /* Insert the newly-assigned ID into the previously-discovered gap,
     which is possibly at the end of the list.  Inserting it there
     keeps the list sorted.  */
  watch_id = make_number (id);
  watch = list4 (watch_id, filename, callback, mask);
  XSETCDR (tail, Fcons (watch, XCDR (tail)));

  return Fcons (descriptor, watch_id);
}
Пример #2
0
static Lisp_Object
inotifyevent_to_event (Lisp_Object watch, struct inotify_event const *ev)
{
  Lisp_Object name;
  uint32_t mask;
  CONS_TO_INTEGER (Fnth (make_number (3), watch), uint32_t, mask);

  if (! (mask & ev->mask))
    return Qnil;

  if (ev->len > 0)
    {
      size_t const len = strlen (ev->name);
      name = make_unibyte_string (ev->name, min (len, ev->len));
      name = DECODE_FILE (name);
    }
  else
    name = XCAR (XCDR (watch));

  return list2 (list4 (Fcons (INTEGER_TO_CONS (ev->wd), XCAR (watch)),
                       mask_to_aspects (ev->mask),
                       name,
		       INTEGER_TO_CONS (ev->cookie)),
		Fnth (make_number (2), watch));
}
Пример #3
0
void
record_first_change (void)
{
  struct buffer *base_buffer = current_buffer;

  if (EQ (BVAR (current_buffer, undo_list), Qt))
    return;

  if (current_buffer != last_undo_buffer)
    Fundo_boundary ();
  last_undo_buffer = current_buffer;

  if (base_buffer->base_buffer)
    base_buffer = base_buffer->base_buffer;

  BVAR (current_buffer, undo_list) =
    Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)),
	   BVAR (current_buffer, undo_list));
}
Пример #4
0
/* This callback is called when the FD is available for read.  The inotify
   events are read from FD and converted into input_events.  */
static void
inotify_callback (int fd, void *_)
{
  int to_read;
  if (ioctl (fd, FIONREAD, &to_read) < 0)
    report_file_notify_error ("Error while retrieving file system events",
			      Qnil);
  USE_SAFE_ALLOCA;
  char *buffer = SAFE_ALLOCA (to_read);
  ssize_t n = read (fd, buffer, to_read);
  if (n < 0)
    report_file_notify_error ("Error while reading file system events", Qnil);

  struct input_event event;
  EVENT_INIT (event);
  event.kind = FILE_NOTIFY_EVENT;

  for (ssize_t i = 0; i < n; )
    {
      struct inotify_event *ev = (struct inotify_event *) &buffer[i];
      Lisp_Object descriptor = INTEGER_TO_CONS (ev->wd);
      Lisp_Object prevtail = find_descriptor (descriptor);

      if (! NILP (prevtail))
        {
	  Lisp_Object tail = CONSP (prevtail) ? XCDR (prevtail) : watch_list;
	  for (Lisp_Object watches = XCDR (XCAR (tail)); ! NILP (watches);
	       watches = XCDR (watches))
            {
              event.arg = inotifyevent_to_event (XCAR (watches), ev);
              if (!NILP (event.arg))
                kbd_buffer_store_event (&event);
            }
          /* If event was removed automatically: Drop it from watch list.  */
          if (ev->mask & IN_IGNORED)
	    remove_descriptor (prevtail, true);
        }
      i += sizeof (*ev) + ev->len;
    }

  SAFE_FREE ();
}
Пример #5
0
static void
x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value,
		 Lisp_Object frame)
{
  struct frame *f = XFRAME (frame);
  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
  Time timestamp = last_event_timestamp;
  OSStatus err;
  Selection sel;
  struct gcpro gcpro1, gcpro2;
  Lisp_Object rest, handler_fn, value, target_type;

  GCPRO2 (selection_name, selection_value);

  block_input ();

  err = mac_get_selection_from_symbol (selection_name, 1, &sel);
  if (err == noErr && sel)
    {
      /* Don't allow a quit within the converter.
	 When the user types C-g, he would be surprised
	 if by luck it came during a converter.  */
      ptrdiff_t count = SPECPDL_INDEX ();
      specbind (Qinhibit_quit, Qt);

      for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest))
	{
	  if (!(CONSP (XCAR (rest))
		&& (target_type = XCAR (XCAR (rest)),
		    SYMBOLP (target_type))
		&& mac_valid_selection_target_p (target_type)
		&& (handler_fn = XCDR (XCAR (rest)),
		    SYMBOLP (handler_fn))))
	    continue;

	  if (!NILP (handler_fn))
	    value = call3 (handler_fn, selection_name,
			   target_type, selection_value);
	  else
	    value = Qnil;

	  if (NILP (value))
	    continue;

	  if (mac_valid_selection_value_p (value, target_type))
	    err = mac_put_selection_value (sel, target_type, value);
	  else if (CONSP (value)
		   && EQ (XCAR (value), target_type)
		   && mac_valid_selection_value_p (XCDR (value), target_type))
	    err = mac_put_selection_value (sel, target_type, XCDR (value));
	}

      unbind_to (count, Qnil);
    }

  unblock_input ();

  UNGCPRO;

  if (sel && err != noErr)
    error ("Can't set selection");

  /* Now update the local cache */
  {
    Lisp_Object selection_data;
    Lisp_Object ownership_info;
    Lisp_Object prev_value;

    if (sel)
      {
	block_input ();
	ownership_info = mac_get_selection_ownership_info (sel);
	unblock_input ();
      }
    else
      ownership_info = Qnil; 	/* dummy value for local-only selection */
    selection_data = list5 (selection_name, selection_value,
			    INTEGER_TO_CONS (timestamp), frame, ownership_info);
    prev_value = LOCAL_SELECTION (selection_name, dpyinfo);

    tset_selection_alist
      (dpyinfo->terminal,
       Fcons (selection_data, dpyinfo->terminal->Vselection_alist));

    /* If we already owned the selection, remove the old selection
       data.  Don't use Fdelq as that may QUIT.  */
    if (!NILP (prev_value))
      {
	/* We know it's not the CAR, so it's easy.  */
	Lisp_Object rest = dpyinfo->terminal->Vselection_alist;
	for (; CONSP (rest); rest = XCDR (rest))
	  if (EQ (prev_value, Fcar (XCDR (rest))))
	    {
	      XSETCDR (rest, XCDR (XCDR (rest)));
	      break;
	    }
      }
  }
}