discord_register_linux.cpp
1 #include "discord_rpc.h" 2 #include "discord_register.h" 3 #include <stdio.h> 4 5 #include <errno.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <sys/stat.h> 9 #include <sys/types.h> 10 #include <unistd.h> 11 12 static bool Mkdir(const char* path) 13 { 14 int result = mkdir(path, 0755); 15 if (result == 0) { 16 return true; 17 } 18 if (errno == EEXIST) { 19 return true; 20 } 21 return false; 22 } 23 24 // we want to register games so we can run them from Discord client as discord-<appid>:// 25 extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) 26 { 27 // Add a desktop file and update some mime handlers so that xdg-open does the right thing. 28 29 const char* home = getenv("HOME"); 30 if (!home) { 31 return; 32 } 33 34 char exePath[1024]; 35 if (!command || !command[0]) { 36 ssize_t size = readlink("/proc/self/exe", exePath, sizeof(exePath)); 37 if (size <= 0 || size >= (ssize_t)sizeof(exePath)) { 38 return; 39 } 40 exePath[size] = '\0'; 41 command = exePath; 42 } 43 44 const char* desktopFileFormat = "[Desktop Entry]\n" 45 "Name=Game %s\n" 46 "Exec=%s %%u\n" // note: it really wants that %u in there 47 "Type=Application\n" 48 "NoDisplay=true\n" 49 "Categories=Discord;Games;\n" 50 "MimeType=x-scheme-handler/discord-%s;\n"; 51 char desktopFile[2048]; 52 int fileLen = snprintf( 53 desktopFile, sizeof(desktopFile), desktopFileFormat, applicationId, command, applicationId); 54 if (fileLen <= 0) { 55 return; 56 } 57 58 char desktopFilename[256]; 59 snprintf(desktopFilename, sizeof(desktopFilename), "/discord-%s.desktop", applicationId); 60 61 char desktopFilePath[1024]; 62 snprintf(desktopFilePath, sizeof(desktopFilePath), "%s/.local", home); 63 if (!Mkdir(desktopFilePath)) { 64 return; 65 } 66 strcat(desktopFilePath, "/share"); 67 if (!Mkdir(desktopFilePath)) { 68 return; 69 } 70 strcat(desktopFilePath, "/applications"); 71 if (!Mkdir(desktopFilePath)) { 72 return; 73 } 74 strcat(desktopFilePath, desktopFilename); 75 76 FILE* fp = fopen(desktopFilePath, "w"); 77 if (fp) { 78 fwrite(desktopFile, 1, fileLen, fp); 79 fclose(fp); 80 } 81 else { 82 return; 83 } 84 85 char xdgMimeCommand[1024]; 86 snprintf(xdgMimeCommand, 87 sizeof(xdgMimeCommand), 88 "xdg-mime default discord-%s.desktop x-scheme-handler/discord-%s", 89 applicationId, 90 applicationId); 91 if (system(xdgMimeCommand) < 0) { 92 fprintf(stderr, "Failed to register mime handler\n"); 93 } 94 } 95 96 extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, 97 const char* steamId) 98 { 99 char command[256]; 100 sprintf(command, "xdg-open steam://rungameid/%s", steamId); 101 Discord_Register(applicationId, command); 102 }