17c804472Sopenharmony_ci/* 27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47c804472Sopenharmony_ci * you may not use this file except in compliance with the License. 57c804472Sopenharmony_ci * You may obtain a copy of the License at 67c804472Sopenharmony_ci * 77c804472Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87c804472Sopenharmony_ci * 97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c804472Sopenharmony_ci * See the License for the specific language governing permissions and 137c804472Sopenharmony_ci * limitations under the License. 147c804472Sopenharmony_ci */ 157c804472Sopenharmony_ci 167c804472Sopenharmony_ci#include "ClipboardX11.h" 177c804472Sopenharmony_ci#include <iostream> 187c804472Sopenharmony_ci#include <cstring> 197c804472Sopenharmony_ci#include <X11/Xlib.h> 207c804472Sopenharmony_ci 217c804472Sopenharmony_civoid ClipboardX11::SetClipboardData(const std::string& str) 227c804472Sopenharmony_ci{ 237c804472Sopenharmony_ci display = XOpenDisplay(0); 247c804472Sopenharmony_ci int ret = DefaultScreen(display); 257c804472Sopenharmony_ci window = XCreateSimpleWindow(display, RootWindow(display, ret), 0, 0, 1, 1, 0, 267c804472Sopenharmony_ci BlackPixel(display, ret), WhitePixel(display, ret)); 277c804472Sopenharmony_ci targets_atom = XInternAtom(display, "TARGETS", 0); 287c804472Sopenharmony_ci text_atom = XInternAtom(display, "TEXT", 0); 297c804472Sopenharmony_ci UTF8 = XInternAtom(display, "UTF8_STRING", 1); 307c804472Sopenharmony_ci if (UTF8 == None) UTF8 = XA_STRING; 317c804472Sopenharmony_ci Atom selection = XInternAtom(display, "CLIPBOARD", 0); 327c804472Sopenharmony_ci SetCopyData(selection, str, strlen(str.c_str())); 337c804472Sopenharmony_ci} 347c804472Sopenharmony_ci 357c804472Sopenharmony_ciconst std::string ClipboardX11::GetClipboardData() 367c804472Sopenharmony_ci{ 377c804472Sopenharmony_ci display = XOpenDisplay(0); 387c804472Sopenharmony_ci int ret = DefaultScreen(display); 397c804472Sopenharmony_ci window = XCreateSimpleWindow(display, RootWindow(display, ret), 0, 0, 1, 1, 0, 407c804472Sopenharmony_ci BlackPixel(display, ret), WhitePixel(display, ret)); 417c804472Sopenharmony_ci std::string retStr; // NOLINT 427c804472Sopenharmony_ci UTF8 = XInternAtom(display, "UTF8_STRING", True); 437c804472Sopenharmony_ci if (UTF8 != None) retStr = GetPasteType(UTF8); 447c804472Sopenharmony_ci if (retStr.empty()) retStr = GetPasteType(XA_STRING); 457c804472Sopenharmony_ci return retStr; 467c804472Sopenharmony_ci} 477c804472Sopenharmony_ci 487c804472Sopenharmony_civoid ClipboardX11::SetCopyData(const Atom& selection, const std::string& text, const int size) 497c804472Sopenharmony_ci{ 507c804472Sopenharmony_ci XEvent event; 517c804472Sopenharmony_ci XSetSelectionOwner (display, selection, window, 0); 527c804472Sopenharmony_ci if (XGetSelectionOwner (display, selection) != window) { 537c804472Sopenharmony_ci return; 547c804472Sopenharmony_ci } 557c804472Sopenharmony_ci while (1) { 567c804472Sopenharmony_ci XNextEvent (display, &event); 577c804472Sopenharmony_ci if (event.type == SelectionRequest) { 587c804472Sopenharmony_ci if (event.xselectionrequest.selection != selection) { 597c804472Sopenharmony_ci break; 607c804472Sopenharmony_ci } 617c804472Sopenharmony_ci XSelectionRequestEvent* xsr = &event.xselectionrequest; 627c804472Sopenharmony_ci XSelectionEvent ev = {0}; 637c804472Sopenharmony_ci int ret = 0; 647c804472Sopenharmony_ci ev.type = SelectionNotify, ev.display = xsr->display, ev.requestor = xsr->requestor, 657c804472Sopenharmony_ci ev.selection = xsr->selection, ev.time = xsr->time, ev.target = xsr->target, 667c804472Sopenharmony_ci ev.property = xsr->property; 677c804472Sopenharmony_ci if (ev.target == targets_atom) { 687c804472Sopenharmony_ci ret = XChangeProperty(ev.display, ev.requestor, ev.property, 697c804472Sopenharmony_ci XA_ATOM, nFormateProp32, PropModeReplace, 707c804472Sopenharmony_ci (unsigned char*)&UTF8, 1); 717c804472Sopenharmony_ci } else if (ev.target == XA_STRING || ev.target == text_atom) { 727c804472Sopenharmony_ci ret = XChangeProperty(ev.display, ev.requestor, ev.property, XA_STRING, 737c804472Sopenharmony_ci nFormateProp8, PropModeReplace, (unsigned char*)text.c_str(), size); 747c804472Sopenharmony_ci } else if (ev.target == UTF8) { 757c804472Sopenharmony_ci ret = XChangeProperty(ev.display, ev.requestor, ev.property, UTF8, 767c804472Sopenharmony_ci nFormateProp8, PropModeReplace, (unsigned char*)text.c_str(), size); 777c804472Sopenharmony_ci } else { 787c804472Sopenharmony_ci ev.property = None; 797c804472Sopenharmony_ci } 807c804472Sopenharmony_ci if ((ret & nEvenNumber) == 0) { 817c804472Sopenharmony_ci XSendEvent (display, ev.requestor, 0, 0, (XEvent *)&ev); 827c804472Sopenharmony_ci } 837c804472Sopenharmony_ci } 847c804472Sopenharmony_ci } 857c804472Sopenharmony_ci} 867c804472Sopenharmony_ci 877c804472Sopenharmony_cistd::string ClipboardX11::GetPasteType(const Atom& atom) 887c804472Sopenharmony_ci{ 897c804472Sopenharmony_ci XEvent event; 907c804472Sopenharmony_ci int format; 917c804472Sopenharmony_ci unsigned long num, size; 927c804472Sopenharmony_ci char* data = nullptr; 937c804472Sopenharmony_ci std::string retStr; 947c804472Sopenharmony_ci Atom target, CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0), XSEL_DATA = XInternAtom(display, "XSEL_DATA", 0); 957c804472Sopenharmony_ci XConvertSelection(display, CLIPBOARD, atom, XSEL_DATA, window, CurrentTime); 967c804472Sopenharmony_ci XSync(display, 0); 977c804472Sopenharmony_ci XNextEvent(display, &event); 987c804472Sopenharmony_ci if (event.type == SelectionNotify) { 997c804472Sopenharmony_ci if (event.xselection.selection != CLIPBOARD) { 1007c804472Sopenharmony_ci return retStr; 1017c804472Sopenharmony_ci } 1027c804472Sopenharmony_ci if (event.xselection.property) { 1037c804472Sopenharmony_ci XGetWindowProperty(event.xselection.display, event.xselection.requestor, event.xselection.property, 0L, 1047c804472Sopenharmony_ci (~0L), 0, AnyPropertyType, &target, &format, &size, &num, (unsigned char**)&data); 1057c804472Sopenharmony_ci if (target == UTF8 || target == XA_STRING) { 1067c804472Sopenharmony_ci std::string str(data); 1077c804472Sopenharmony_ci retStr = str; 1087c804472Sopenharmony_ci } 1097c804472Sopenharmony_ci XFree(data); 1107c804472Sopenharmony_ci XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property); 1117c804472Sopenharmony_ci } 1127c804472Sopenharmony_ci } 1137c804472Sopenharmony_ci return retStr; 1147c804472Sopenharmony_ci}