static int x_selection_owner_p (Lisp_Object selection, struct mac_display_info *dpyinfo) { OSStatus err; Selection sel; Lisp_Object local_selection_data; int result = 0; local_selection_data = LOCAL_SELECTION (selection, dpyinfo); if (NILP (local_selection_data)) return 0; block_input (); err = mac_get_selection_from_symbol (selection, 0, &sel); if (err == noErr && sel) { Lisp_Object ownership_info; ownership_info = XCAR (XCDR (XCDR (XCDR (XCDR (local_selection_data))))); if (!NILP (Fequal (ownership_info, mac_get_selection_ownership_info (sel)))) result = 1; } else result = 1; unblock_input (); return result; }
/* This compares two directory listings in case of a `write' event for a directory. Generate resulting file notification events. The old directory listing is retrieved from watch_object, it will be replaced by the new directory listing at the end of this function. */ static void kqueue_compare_dir_list (Lisp_Object watch_object) { Lisp_Object dir, pending_dl, deleted_dl; Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl; dir = XCAR (XCDR (watch_object)); pending_dl = Qnil; deleted_dl = Qnil; old_directory_files = Fnth (make_number (4), watch_object); old_dl = kqueue_directory_listing (old_directory_files); /* When the directory is not accessible anymore, it has been deleted. */ if (NILP (Ffile_directory_p (dir))) { kqueue_generate_event (watch_object, Fcons (Qdelete, Qnil), dir, Qnil); return; } new_directory_files = directory_files_internal (dir, Qnil, Qnil, Qnil, 1, Qnil); new_dl = kqueue_directory_listing (new_directory_files); /* Parse through the old list. */ dl = old_dl; while (1) { Lisp_Object old_entry, new_entry, dl1; if (NILP (dl)) break; /* Search for an entry with the same inode. */ old_entry = XCAR (dl); new_entry = assq_no_quit (XCAR (old_entry), new_dl); if (! NILP (Fequal (old_entry, new_entry))) { /* Both entries are identical. Nothing to do. */ new_dl = Fdelq (new_entry, new_dl); goto the_end; } /* Both entries have the same inode. */ if (! NILP (new_entry)) { /* Both entries have the same file name. */ if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { /* Modification time has been changed, the file has been written. */ if (NILP (Fequal (Fnth (make_number (2), old_entry), Fnth (make_number (2), new_entry)))) kqueue_generate_event (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil); /* Status change time has been changed, the file attributes have changed. */ if (NILP (Fequal (Fnth (make_number (3), old_entry), Fnth (make_number (3), new_entry)))) kqueue_generate_event (watch_object, Fcons (Qattrib, Qnil), XCAR (XCDR (old_entry)), Qnil); } else { /* The file has been renamed. */ kqueue_generate_event (watch_object, Fcons (Qrename, Qnil), XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); deleted_dl = Fcons (new_entry, deleted_dl); } new_dl = Fdelq (new_entry, new_dl); goto the_end; } /* Search, whether there is a file with the same name but another inode. */ for (dl1 = new_dl; ! NILP (dl1); dl1 = XCDR (dl1)) { new_entry = XCAR (dl1); if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { pending_dl = Fcons (new_entry, pending_dl); new_dl = Fdelq (new_entry, new_dl); goto the_end; } } /* Check, whether this a pending file. */ new_entry = assq_no_quit (XCAR (old_entry), pending_dl); if (NILP (new_entry)) { /* Check, whether this is an already deleted file (by rename). */ for (dl1 = deleted_dl; ! NILP (dl1); dl1 = XCDR (dl1)) { new_entry = XCAR (dl1); if (strcmp (SSDATA (XCAR (XCDR (old_entry))), SSDATA (XCAR (XCDR (new_entry)))) == 0) { deleted_dl = Fdelq (new_entry, deleted_dl); goto the_end; } } /* The file has been deleted. */ kqueue_generate_event (watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil); } else { /* The file has been renamed. */ kqueue_generate_event (watch_object, Fcons (Qrename, Qnil), XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry))); pending_dl = Fdelq (new_entry, pending_dl); } the_end: dl = XCDR (dl); old_dl = Fdelq (old_entry, old_dl); } /* Parse through the resulting new list. */ dl = new_dl; while (1) { Lisp_Object entry; if (NILP (dl)) break; /* A new file has appeared. */ entry = XCAR (dl); kqueue_generate_event (watch_object, Fcons (Qcreate, Qnil), XCAR (XCDR (entry)), Qnil); /* Check size of that file. */ Lisp_Object size = Fnth (make_number (4), entry); if (FLOATP (size) || (XINT (size) > 0)) kqueue_generate_event (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil); dl = XCDR (dl); new_dl = Fdelq (entry, new_dl); } /* Parse through the resulting pending_dl list. */ dl = pending_dl; while (1) { Lisp_Object entry; if (NILP (dl)) break; /* A file is still pending. Assume it was a write. */ entry = XCAR (dl); kqueue_generate_event (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil); dl = XCDR (dl); pending_dl = Fdelq (entry, pending_dl); } /* At this point, old_dl, new_dl and pending_dl shall be empty. deleted_dl might not be empty when there was a rename to a nonexistent file. Let's make a check for this (might be removed once the code is stable). */ if (! NILP (old_dl)) report_file_error ("Old list not empty", old_dl); if (! NILP (new_dl)) report_file_error ("New list not empty", new_dl); if (! NILP (pending_dl)) report_file_error ("Pending events list not empty", pending_dl); // if (! NILP (deleted_dl)) // report_file_error ("Deleted events list not empty", deleted_dl); /* Replace old directory listing with the new one. */ XSETCDR (Fnthcdr (make_number (3), watch_object), Fcons (new_directory_files, Qnil)); return; }
int gh_equal_p(repv x, repv y) { repv val = Fequal (x, y); return val && val != Qnil; }