Browse Source

init

main_gtk3
Murloc Knight 6 months ago
commit
20c77a1e8a
Signed by: cyber_flower GPG Key ID: AA6E5F1D70360D15
  1. 6
      .gitmodules
  2. 1
      json
  3. 27
      linux_client/CMakeLists.txt
  4. 93
      linux_client/client.cpp
  5. 15
      linux_client/client.h
  6. 162
      linux_client/main.cpp
  7. 94
      linux_client/server.cpp
  8. 14
      linux_client/server.h
  9. 1
      socket-cpp
  10. 15
      windows_client/CMakeLists.txt
  11. 100
      windows_client/client.cpp
  12. 15
      windows_client/client.h
  13. 218
      windows_client/main.cpp
  14. 106
      windows_client/server.cpp
  15. 14
      windows_client/server.h

6
.gitmodules

@ -0,0 +1,6 @@
[submodule "socket-cpp"]
path = socket-cpp
url = https://github.com/embeddedmz/socket-cpp
[submodule "json"]
path = json
url = https://github.com/nlohmann/json

1
json

@ -0,0 +1 @@
Subproject commit a563338039346c9ed722e09547419190b1eeddbe

27
linux_client/CMakeLists.txt

@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.14)
project(s_clipboard)
set(NOTIFY on)
find_package(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS})
ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER})
set(CMAKE_CXX_STANDARD 17)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../socket-cpp socket-cpp)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../json/ json)
if(NOTIFY)
find_library(NOTIFY notify)
add_definitions(-DNOTIFY)
endif()
include_directories(../socket-cpp/Socket)
include_directories(../json/include)
add_executable(${PROJECT_NAME} main.cpp server.cpp server.h client.cpp client.h)
target_link_libraries(${PROJECT_NAME} ${GTK3_LIBRARIES} pthread socket ${NOTIFY})

93
linux_client/client.cpp

@ -0,0 +1,93 @@
//
// Created by Victor on 16.07.2021.
//
#include <iostream>
#include "client.h"
#include <TCPClient.h>
#include <thread>
#include <codecvt>
#include <locale>
static const auto LogPrinter = [](const std::string& strLogMsg) { std::cout << strLogMsg << std::endl; };
static void (*callback)(std::string*);
static CTCPClient* client = nullptr;
static bool isConnected;
static bool isShutdown = false;
bool client_is_connected(){
return isConnected;
}
void listenServer(){
while(true){
int size;
int ret = client->Receive((char*) &size, sizeof(int));
if(ret == 0){
break;
}
if(size == -1){
break;
}
std::string *msg = nullptr;
try {
msg = new std::string(size + 1, ' ');
}catch(std::exception& e){
break;
}
client->Receive(msg->data(),size);
std::cout << msg << std::endl;
callback(msg);
}
client->Disconnect();
}
void disconnect_client(){
if(isConnected){
int msg = -1;
client->Send((char*) &msg, sizeof(int));
client->Disconnect();
}
}
void sendData_client(std::string* msg){
if(isConnected){
int size = msg->size();
client->Send((char*) &size, sizeof(int));
client->Send((char*) msg->data());
}
}
bool init_client(std::string ip, std::string port, void (*_callback)(std::string*)){
callback = _callback;
client = new CTCPClient(LogPrinter);
isConnected = client->Connect(ip,port);
if(!isConnected){
delete client;
return false;
}
std::thread(listenServer).detach();
return true;
}

15
linux_client/client.h

@ -0,0 +1,15 @@
//
// Created by Victor on 16.07.2021.
//
#ifndef S_CLIPBOARD_CLIENT_H
#define S_CLIPBOARD_CLIENT_H
#include <string>
bool init_client(std::string ip, std::string port, void (*_callback)(std::string*));
bool client_is_connected();
void sendData_client(std::string* msg);
void disconnect_client();
#endif //S_CLIPBOARD_CLIENT_H

162
linux_client/main.cpp

@ -0,0 +1,162 @@
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <thread>
#include <iostream>
#include "server.h"
#include "client.h"
#include <csignal>
#include <nlohmann/json.hpp>
#include <vector>
#include <pwd.h>
#include <fstream>
#include <libnotify/notify.h>
using namespace nlohmann;
typedef struct {
std::string name;
std::string ip;
std::string port;
}Client;
GtkClipboard *clipboard;
bool isSet = false;
std::string port;
std::vector<Client> clients;
void sendData(std::string* msg);
void signalHandle(int sig){
std::cout << "disconnect" << std::endl;
disconnect_client();
disconnect_server();
exit(sig);
}
void wait_text(){
if(isSet){
isSet = false;
return;
}
gchar* msg = gtk_clipboard_wait_for_text(clipboard);
printf("%s\n",msg);
auto* s_msg = new std::string(msg);
sendData(s_msg);
}
gboolean set_clipboard(std::string* msg){
isSet = true;
gtk_clipboard_set_text(clipboard, msg->data(), -1);
#ifdef DNOTIFY
std::string short_msg(23, '.');
for (int i = 0; i < 20 && i < msg->length(); ++i) {
short_msg[i] = (*msg)[i];
}
NotifyNotification* notify = notify_notification_new(clients[0].name.data(), short_msg.data(),"clipit-trayicon");
GError* err = nullptr;
notify_notification_show(notify,&err);
g_object_unref(notify);
#endif
delete msg;
return false;
}
void load_config(std::string file){
try {
std::ifstream stream(file);
json config;
stream >> config;
port = config["port"];
json clients_json = config["clients"];
for(json& client_json : clients_json){
Client client;
client.name = client_json["name"];
client.ip = client_json["ip"];
client.port = client_json["port"];
clients.push_back(client);
}
}catch(std::exception& e){
std::cout << "incorrect configurate file" << std::endl;
exit(-1);
}
}
void sendData(std::string* msg){
if(client_is_connected()){
sendData_client(msg);
}
if(server_is_connected()){
sendData_server(msg);
}
delete msg;
}
void callback(std::string* msg){
g_idle_add(G_SOURCE_FUNC(set_clipboard),msg);
}
std::string get_default_path(){
const char* home = getenv("HOME");
if(home == nullptr){
home = getpwuid(getuid())->pw_dir;
}
std::string result = home + std::string("/.config/shared clipboard/config.json");
std::cout << result << std::endl;
return result;
}
int main(int argc, char** argv)
{
std::string config_file = get_default_path();
if(argc >= 3){
if(std::string("--config") == argv[1]){
config_file = std::string(argv[2]);
}
}
load_config(config_file);
signal(15,signalHandle);
notify_init("shared clipboard");
gtk_init(&argc, &argv);
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
init_client(clients[0].ip,clients[0].port,callback);
init_server(port, callback);
g_signal_connect(clipboard,"owner-change",wait_text,NULL);
gtk_main();
return 0;
}

94
linux_client/server.cpp

@ -0,0 +1,94 @@
//
// Created by Victor on 15.07.2021.
//
#include "server.h"
#include <TCPServer.h>
#include <Socket.h>
#include <thread>
#include <iostream>
#include <codecvt>
#include <locale>
static auto LogPrinter = [](const std::string& strLogMsg) { std::cout << strLogMsg << std::endl; };
static void (*callback)(std::string*);
static CTCPServer* server = nullptr;
static ASocket::Socket client;
static bool isConnected = false;
static bool isShutDown = false;
bool server_is_connected(){
return isConnected;
}
void disconnect_server(){
if(isConnected){
int msg = -1;
server->Send(client, (char*) &msg, sizeof(int));
isShutDown = true;
isConnected = false;
}
}
void listenClients(){
server->Listen(client);
isConnected = true;
printf("\nconnected\n");
while(true){
int size;
int ret = server->Receive(client,(char*) &size, sizeof(int));
// std::cout << ret << std::endl;
if(size == -1 || ret == 0){
break;
}
// std::string msg(size + 1,' ');
auto* msg = new std::string(size + 1,' ');
server->Receive(client,(char*) msg->data(),size);
callback(msg);
}
if(!isShutDown){
listenClients();
}
int msg = -1;
server->Send(client, (char*) &msg, sizeof(int));
server->Disconnect(client);
// int msg = -1;
//
// server->Send(client, (char*) &msg, sizeof(int));
//
// server->Disconnect(client);
}
void sendData_server(std::string* msg){
if(isConnected){
int size = msg->size();
server->Send(client,(char*) &size, sizeof(int));
server->Send(client,(char*) msg->data());
}
}
bool init_server(std::string port, void (*_callback)(std::string*)){
server = new CTCPServer(LogPrinter,port);
std::thread(listenClients).detach();
callback = _callback;
return true;
}

14
linux_client/server.h

@ -0,0 +1,14 @@
//
// Created by Victor on 15.07.2021.
//
#ifndef CLIPBOAD_TEST_SERVER_H
#define CLIPBOAD_TEST_SERVER_H
#include <string>
bool init_server(std::string port, void (*_callback)(std::string*));
void sendData_server(std::string* msg);
bool server_is_connected();
void disconnect_server();
#endif //CLIPBOAD_TEST_SERVER_H

1
socket-cpp

@ -0,0 +1 @@
Subproject commit 98ed1669ce0b90362924c19e079d1e2f12e1db41

15
windows_client/CMakeLists.txt

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.18)
project(s_clipboard)
set(CMAKE_CXX_STANDARD 17)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../socket-cpp socket-cpp)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../json/ json)
include_directories(../socket-cpp/Socket)
include_directories(../json/include)
set(CMAKE_CXX_FLAGS "-mwindows")
add_executable(${PROJECT_NAME} main.cpp server.cpp server.h client.cpp client.h)
target_link_libraries(${PROJECT_NAME} socket nlohmann_json)

100
windows_client/client.cpp

@ -0,0 +1,100 @@
//
// Created by Victor on 16.07.2021.
//
#include <iostream>
#include "client.h"
#include <TCPClient.h>
#include <thread>
#include <codecvt>
#include <locale>
static const auto LogPrinter = [](const std::string& strLogMsg) { std::wcout << strLogMsg.data() << std::endl; };
static void (*callback)(std::wstring*);
static CTCPClient* client = nullptr;
static bool isConnected;
bool client_is_connected(){
return isConnected;
}
static std::wstring* utf8_to_wstring (const std::string* str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return new std::wstring(myconv.from_bytes(str->data()));
}
static std::string* wstring_to_utf8 (const std::wstring* str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return new std::string(myconv.to_bytes(str->data()));
}
void listenServer(){
while(true){
int size;
client->Receive((char*) &size, sizeof(int));
if(size == -1){
break;
}
auto* msg_utf8 = new std::string(size + 1, ' ');
client->Receive(msg_utf8->data(),size);
std::wstring* w_msg = utf8_to_wstring(msg_utf8);
std::wcout << w_msg << std::endl;
delete msg_utf8;
callback(w_msg);
}
client->Disconnect();
}
void sendData_client(std::wstring* msg){
if(isConnected){
std::string* msg_utf8 = wstring_to_utf8(msg);
int size = msg_utf8->size();
client->Send((char*) &size, sizeof(int));
client->Send((char*) msg_utf8->data());
}
}
void disconnect_client(){
if(isConnected){
int msg = -1;
client->Send((char*) &msg, sizeof(int));
client->Disconnect();
}
}
bool init_client(std::string ip, std::string port, void (*_callback)(std::wstring*)){
callback = _callback;
client = new CTCPClient(LogPrinter);
isConnected = client->Connect(ip,port);
if(!isConnected){
delete client;
return false;
}
std::thread(listenServer).detach();
return true;
}

15
windows_client/client.h

@ -0,0 +1,15 @@
//
// Created by Victor on 16.07.2021.
//
#ifndef S_CLIPBOARD_CLIENT_H
#define S_CLIPBOARD_CLIENT_H
#include <string>
bool client_is_connected();
void sendData_client(std::wstring* msg);
void disconnect_client();
bool init_client(std::string ip, std::string port, void (*_callback)(std::wstring*));
#endif //S_CLIPBOARD_CLIENT_H

218
windows_client/main.cpp

@ -0,0 +1,218 @@
#define WINVER 0x0600
#define NTDDI_VERSION 0x06010000
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <winuser.h>
#include "server.h"
#include "client.h"
#include <signal.h>
#include <nlohmann/json.hpp>
#include <fstream>
#include <vector>
#include <shellapi.h>
#include <commctrl.h>
#include <strsafe.h>
#include <unistd.h>
#include <cstdlib>
UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1;
UINT const WMAPP_HIDEFLYOUT = WM_APP + 2;
UINT_PTR const HIDEFLYOUT_TIMER_ID = 1;
using namespace std;
using namespace nlohmann;
typedef struct {
string name;
string ip;
string port;
}Client;
static TCHAR szWindowClass[] = _T("DesktopApp");
static string port;
static vector<Client> clients;
void read_config();
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool isSet = false;
void setClipboard(wstring* msg);
void signalHandler(int signum ) {
disconnect_client();
disconnect_server();
exit(0);
}
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
){
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
read_config();
setlocale(LC_ALL, "");
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T(""),
0);
return 1;
}
HWND hWnd = CreateWindowEx(0, szWindowClass, _T("s_clipboard"),
0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T(""),
0);
return 1;
}
SetClipboardViewer(hWnd);
init_client(clients[0].ip,clients[0].port,setClipboard);
init_server(port, setClipboard);
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
void read_config(){
ifstream stream("config.json");
json config;
stream >> config;
port = config["port"];
wcout << port.data() << endl;
json clients_json = config["clients"];
for(json& client_json : clients_json){
Client client;
client.name = client_json["name"];
wcout << client.name.data() << endl;
client.ip = client_json["ip"];
wcout << client.ip.data() << endl;
client.port = client_json["port"];
wcout << client.port.data() << endl;
clients.push_back(client);
}
}
std::wstring* GetClipboardText()
{
OpenClipboard(nullptr);
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
void* tmp = GlobalLock(hData);
char * pszText = static_cast<char*>(tmp);
auto* text = new std::wstring((wchar_t *) pszText);
GlobalUnlock( hData );
CloseClipboard();
return text;
}
void setClipboard(wstring* msg){
isSet = true;
OpenClipboard(nullptr);
EmptyClipboard();
HGLOBAL clipbuffer = GlobalAlloc(GMEM_DDESHARE, (msg->size()*2)+1);
auto* buffer = (wchar_t *)GlobalLock(clipbuffer);
memcpy(buffer,msg->data(),msg->size()*2);
GlobalUnlock(clipbuffer);
SetClipboardData(CF_UNICODETEXT,clipbuffer);
CloseClipboard();
delete msg;
}
void sendData(std::wstring* msg){
if(client_is_connected()){
sendData_client(msg);
}
if(server_is_connected()){
sendData_server(msg);
}
delete msg;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_DRAWCLIPBOARD){
if(isSet){
isSet = false;
return 0;
}
wstring* msg = GetClipboardText();
sendData(msg);
}else{
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

106
windows_client/server.cpp

@ -0,0 +1,106 @@
//
// Created by Victor on 15.07.2021.
//
#include "server.h"
#include <TCPServer.h>
#include <Socket.h>
#include <thread>
#include <iostream>
#include <codecvt>
#include <locale>
static const auto LogPrinter = [](const std::string& strLogMsg) { std::wcout << strLogMsg.data() << std::endl; };
static void (*callback)(std::wstring*);
static CTCPServer* server = nullptr;
static ASocket::Socket client;
static bool isConnected = false;
static bool isShutdown = false;
bool server_is_connected(){
return isConnected;
}
static std::wstring* utf8_to_wstring (const std::string* str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return new std::wstring(myconv.from_bytes(str->data()));
}
static std::string* wstring_to_utf8 (const std::wstring* str)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return new std::string(myconv.to_bytes(str->data()));
}
void disconnect_server(){
if(isConnected){
int msg = -1;
server->Send(client, (char*) &msg, sizeof(int));
server->Disconnect(client);
isConnected = false;
isShutdown = true;
}
}
void listenClients(){
server->Listen(client);
isConnected = true;
printf("\nconnected\n");
while(true){
int size;
server->Receive(client,(char*) &size, sizeof(int));
if(size == -1){
break;
}
// std::string msg(size + 1,' ');
auto* msg = new std::string(size + 1, ' ');
server->Receive(client,(char*) msg->data(),size);
std::wstring* w_msg = utf8_to_wstring(msg);
std::wcout << w_msg << std::endl;
callback(w_msg);
delete msg;
}
if(!isShutdown){
listenClients();
}
}
void sendData_server(std::wstring* msg){
if(isConnected){
std::string* msg_utf8 = wstring_to_utf8(msg);
int size = msg_utf8->size();
server->Send(client,(char*) &size, sizeof(int));
server->Send(client,(char*) msg_utf8->data());
}
}
bool init_server(std::string port, void (*_callback)(std::wstring*)){
server = new CTCPServer(LogPrinter,port);
std::thread(listenClients).detach();
callback = _callback;
return true;
}

14
windows_client/server.h

@ -0,0 +1,14 @@
//
// Created by Victor on 15.07.2021.
//
#ifndef S_CLIPBOARD_SERVER_H
#define S_CLIPBOARD_SERVER_H
#include <string>
bool init_server(std::string port, void (*_callback)(std::wstring*));
void sendData_server(std::wstring* msg);
bool server_is_connected();
void disconnect_server();
#endif //S_CLIPBOARD_SERVER_H
Loading…
Cancel
Save