Как работают Ctrl+C и Ctrl+V?
Мне всегда было интересно, что происходит под капотом (в операционной системе), когда я копирую изображение (выбирая его и используя Ctrl+C) в файл Word (например, вставляя его с помощью Ctrl+V).
1 ответ
В Windows ОС буфера обмена и буфер хранения предоставляются ОС на уровне ядра. (Буфер обмена принадлежит объекту ядра "оконная станция".)
Ctrl + C указывает программе сохранять "скопированные" данные с помощью функции Win32 API
SetClipboardData()
что также соответствуетNtUserSetClipboardData()
в родном API.Обычно скопированные данные немедленно сохраняются в буфере буфера обмена под управлением ОС и больше не зависят от исходной программы. Программа может предоставлять несколько различных форматов - например, текст, скопированный из MS Word, может одновременно быть представлен в форматах HTML, RTF и в виде открытого текста.
(Тем не менее, программа может сохранить нулевые данные и отложить преобразование, пока не будет запрошена вставка с использованием
WM_RENDERFORMAT
, В этом случае данные теряются при закрытии программы. Я не уверен, насколько распространен этот метод.)Ctrl + V говорит программе выбрать нужный формат и получить его, используя
GetClipboardData()
, Некоторые программы, например WordPad или Paint, имеют функцию "Вставить как", которая позволяет выбрать предпочтительный формат (например, если вы скопировали HTML, но не хотите форматировать).Смотрите также сообщение в блоге "Отладка NT: как работает буфер обмена".
В Linux нет общесистемного буфера обмена, вместо этого он предоставляется любой графической средой, которую вы используете (то есть X11, Wayland, нет):
В X11 (не обязательно только в Linux) перенос буфера обмена отложен. То есть хранилище обеспечивается программой-источником. Обмен осуществляется через сообщения X11 в соответствии с протоколом ICCCM (поэтому буфер обмена изолирован от X-сервера):
Ctrl + C говорит исходной программе зарезервировать "скопированные" данные в своей собственной памяти и запросить выбор X11 под названием "CLIPBOARD". Это делается с помощью
XSetSelectionOwner()
и право собственности отслеживается X-сервером (Xorg).Если вы что-то скопировали ранее, предыдущий владелец выбора уведомляется об этом и удаляет ненужные данные.
Если вы закроете программу, скопированные данные будут потеряны. (Менеджеры буфера обмена могут использоваться, чтобы избежать этого, наблюдая и дублируя текущий выбор.)
Ctrl + V указывает целевой программе искать текущего владельца выбора "CLIPBOARD", используя
XGetSelectionOwner()
затем напрямую запрашивает предпочтительный тип, используяXConvertSelection()
, Затем исходная программа возвращает данные через другое сообщение X11, преобразованное по запросу в тип, который был запрошен. (Существует также специальный тип, который возвращает список возможных типов.)Смотрите эту ссылку для практического примера.
(Примечание. Когда вы "копируете" текст, выделяя его и вставляя его с помощью среднего щелчка, механизм остается тем же, но вместо этого используется выбор "ОСНОВНОЙ". Отсюда и происходит термин "выбор X11".)
В Уэйленде - я на самом деле не понимаю, как это работает, у меня есть только документы по протоколу:
См. https://github.com/bugaevc/wl-clipboard для инструмента командной строки.
Традиционные текстовые редакторы (Vim, emacs, nano) часто имеют свои собственные внутренние буферы обмена (то есть буферы /killrings). Они могут или не могут также интегрироваться с буфером обмена X11.
В macOS, по-видимому, используется нечто, называемое "сервер монтажа" (что, я думаю, означает, что программы взаимодействуют с ним через API-интерфейсы Mach). Кроме этого, он ведет себя как буфер обмена Windows и хранит сами скопированные в данный момент данные.
https://developer.apple.com/documentation/appkit/nspasteboard
Вот пример приложения: https://developer.apple.com/library/archive/samplecode/ClipboardViewer/Introduction/Intro.html
Я более заинтригован с изображениями, как их можно так легко скопировать
Изображения - это просто фрагменты двоичных данных, таких как текст или аудио. Буфер обмена обычно содержит изображения в форматах, общих для ОС, например, BMP в Windows, image / png в Linux.
А в Linux протокол буфера обмена X11 фактически позволяет одному X-клиенту предлагать разные "кодировки" выбора другим клиентам, а принимающий X-клиент может выбирать кодировку, поэтому отправляющий X-клиент получает возможность преобразовать выборку в любой формат: клиенты понимают. По крайней мере, в теории; не уверен, что современные библиотеки инструментария, такие как GTK или Qt, предлагают большой выбор.