mirror of
https://github.com/Goldenkrew3000/OSSP_OpenSource.git
synced 2025-12-19 00:04:44 +10:00
Adding dotfile support, a VERY BASIC GUI, and basic discord rpc
This commit is contained in:
@@ -8,15 +8,14 @@ project(ossp)
|
|||||||
|
|
||||||
find_package(CURL REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
|
find_package(OpenGL REQUIRED)
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
|
||||||
qt_standard_project_setup()
|
add_subdirectory(external/discord-rpc)
|
||||||
|
|
||||||
qt_add_executable(ossp
|
add_executable(ossp MACOSX_BUNDLE
|
||||||
main.c
|
main.c
|
||||||
gui/gui_entry.cpp
|
gui/gui_entry.cpp
|
||||||
gui/window.cpp
|
|
||||||
gui/songWidget.cpp
|
|
||||||
configHandler.c
|
configHandler.c
|
||||||
libopensubsonic/crypto.c
|
libopensubsonic/crypto.c
|
||||||
libopensubsonic/httpclient.c
|
libopensubsonic/httpclient.c
|
||||||
@@ -39,6 +38,18 @@ qt_add_executable(ossp
|
|||||||
external/cJSON_Utils.c
|
external/cJSON_Utils.c
|
||||||
external/libcurl_uriescape.c
|
external/libcurl_uriescape.c
|
||||||
external/md5.c
|
external/md5.c
|
||||||
|
external/imgui/imgui.cpp
|
||||||
|
external/imgui/imgui_tables.cpp
|
||||||
|
external/imgui/imgui_draw.cpp
|
||||||
|
external/imgui/imgui_widgets.cpp
|
||||||
|
external/imgui/imgui_demo.cpp
|
||||||
|
external/imgui/backends/imgui_impl_sdl2.cpp
|
||||||
|
external/imgui/backends/imgui_impl_opengl2.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(ossp PRIVATE OpenSSL::SSL OpenSSL::Crypto CURL::libcurl Qt6::Core Qt6::Widgets)
|
set_target_properties(ossp PROPERTIES
|
||||||
|
MACOSX_BUNDLE_BUNDLE_NAME "OSSP"
|
||||||
|
MACOSX_BUNDLE_GUI_IDENTIFIER "org.hojuix.ossp"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(ossp PRIVATE OpenSSL::SSL OpenSSL::Crypto CURL::libcurl SDL2::SDL2 ${OPENGL_LIBRARIES} discord-rpc)
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ int configHandler_Read(configHandler_config_t** configObj) {
|
|||||||
printf("iOS Container Path: %s\n", config_path);
|
printf("iOS Container Path: %s\n", config_path);
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
#else
|
#else
|
||||||
rc = asprintf(&config_path, "config.json");
|
char* root_path = getenv("HOME");
|
||||||
|
rc = asprintf(&config_path, "%s/.config/ossp/config.json", root_path);
|
||||||
#endif // defined(__APPLE__) && defined(__MACH__) && defined(XCODE)
|
#endif // defined(__APPLE__) && defined(__MACH__) && defined(XCODE)
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
logger_log_error(__func__, "asprintf() failed (Could not generate config path).");
|
logger_log_error(__func__, "asprintf() failed (Could not generate config path).");
|
||||||
|
|||||||
173
src/gui/gui_entry.cpp
Normal file
173
src/gui/gui_entry.cpp
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
#include "../external/imgui/imgui.h"
|
||||||
|
#include "../external/imgui/backends/imgui_impl_sdl2.h"
|
||||||
|
#include "../external/imgui/backends/imgui_impl_opengl2.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_opengl.h>
|
||||||
|
#include "gui_entry.hpp"
|
||||||
|
#include "../configHandler.h"
|
||||||
|
#include "../libopensubsonic/httpclient.h"
|
||||||
|
#include "../libopensubsonic/endpoint_getStarred.h"
|
||||||
|
|
||||||
|
extern configHandler_config_t* configObj;
|
||||||
|
bool bLikedSongsShow = false;
|
||||||
|
void showLikedSongs();
|
||||||
|
|
||||||
|
int qt_gui_entry(int argc, char** argv) {
|
||||||
|
// Initialize SDL
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
|
||||||
|
printf("SDL could not be initialized: %s\n", SDL_GetError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup window
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||||
|
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||||
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
|
SDL_Window* window = SDL_CreateWindow("OSSP v0.3a", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||||
|
if (window == nullptr) {
|
||||||
|
printf("SDL could not create window: %s\n", SDL_GetError());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create GL context
|
||||||
|
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||||
|
SDL_GL_MakeCurrent(window, gl_context);
|
||||||
|
SDL_GL_SetSwapInterval(1); // Vsync
|
||||||
|
|
||||||
|
// Create ImGui context
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
|
// Scaling
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale);
|
||||||
|
style.FontScaleDpi = main_scale;
|
||||||
|
|
||||||
|
// Setup platform/renderer backends
|
||||||
|
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
||||||
|
ImGui_ImplOpenGL2_Init();
|
||||||
|
|
||||||
|
// START START START
|
||||||
|
ImVec4 background_color = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
// Poll events
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
|
if (event.type == SDL_QUIT) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) {
|
||||||
|
SDL_Delay(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start new frame
|
||||||
|
ImGui_ImplOpenGL2_NewFrame();
|
||||||
|
ImGui_ImplSDL2_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
{
|
||||||
|
ImGui::Begin("OSSP v0.3a");
|
||||||
|
|
||||||
|
ImGui::Text("Connected to server at %s://%s", configObj->opensubsonic_protocol, configObj->opensubsonic_server);
|
||||||
|
if (ImGui::Button("Liked Songs")) {
|
||||||
|
printf("Liked songs button pressed\n");
|
||||||
|
bLikedSongsShow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bLikedSongsShow) {
|
||||||
|
showLikedSongs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render
|
||||||
|
ImGui::Render();
|
||||||
|
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||||
|
glClearColor(background_color.x * background_color.w, background_color.y * background_color.w, background_color.z * background_color.w, background_color.w);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
ImGui_ImplOpenGL2_Shutdown();
|
||||||
|
ImGui_ImplSDL2_Shutdown();
|
||||||
|
ImGui::DestroyContext();
|
||||||
|
SDL_GL_DeleteContext(gl_context);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool haveLikedSongsInfo = false;
|
||||||
|
opensubsonic_getStarred_struct* starredStruct;
|
||||||
|
opensubsonic_httpClient_URL_t* starredUrl;
|
||||||
|
|
||||||
|
void getLikedSongsInfo() {
|
||||||
|
// Pull liked songs
|
||||||
|
starredUrl = (opensubsonic_httpClient_URL_t*)malloc(sizeof(opensubsonic_httpClient_URL_t));
|
||||||
|
opensubsonic_httpClient_URL_prepare(&starredUrl);
|
||||||
|
starredUrl->endpoint = OPENSUBSONIC_ENDPOINT_GETSTARRED;
|
||||||
|
opensubsonic_httpClient_formUrl(&starredUrl);
|
||||||
|
opensubsonic_httpClient_fetchResponse(&starredUrl, (void**)&starredStruct);
|
||||||
|
|
||||||
|
if (starredStruct->errorCode != 0) {
|
||||||
|
// Error occured
|
||||||
|
}
|
||||||
|
|
||||||
|
haveLikedSongsInfo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showLikedSongs() {
|
||||||
|
if (!haveLikedSongsInfo) { getLikedSongsInfo(); }
|
||||||
|
|
||||||
|
ImGui::Begin("Liked Songs");
|
||||||
|
|
||||||
|
ImGui::Text("Liked Songs");
|
||||||
|
|
||||||
|
if (ImGui::Button("Close")) {
|
||||||
|
bLikedSongsShow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Refresh")) {
|
||||||
|
opensubsonic_getStarred_struct_free(&starredStruct);
|
||||||
|
opensubsonic_httpClient_URL_cleanup(&starredUrl);
|
||||||
|
haveLikedSongsInfo = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int selectedSong = -1;
|
||||||
|
if (ImGui::BeginChild("Liked Songs", ImVec2(0, 200), ImGuiChildFlags_Border)) {
|
||||||
|
for (int i = 0; i < starredStruct->songCount; i++) {
|
||||||
|
if (ImGui::Selectable(starredStruct->songs[i].title, selectedSong == i)) {
|
||||||
|
selectedSong = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedSong != -1) {
|
||||||
|
printf("Song: %s (%s)\n", starredStruct->songs[selectedSong].title,
|
||||||
|
starredStruct->songs[selectedSong].id);
|
||||||
|
selectedSong = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
15
src/gui/gui_entry.hpp
Normal file
15
src/gui/gui_entry.hpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#ifndef _GUI_ENTRY_HPP
|
||||||
|
#define _GUI_ENTRY_HPP
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
int qt_gui_entry(int argc, char** argv);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
53
src/main.c
53
src/main.c
@@ -1,6 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "external/discord-rpc/include/discord_rpc.h"
|
||||||
#include "gui/gui_entry.hpp"
|
#include "gui/gui_entry.hpp"
|
||||||
#include "libopensubsonic/logger.h"
|
#include "libopensubsonic/logger.h"
|
||||||
#include "libopensubsonic/crypto.h"
|
#include "libopensubsonic/crypto.h"
|
||||||
@@ -8,6 +9,53 @@
|
|||||||
#include "libopensubsonic/endpoint_ping.h"
|
#include "libopensubsonic/endpoint_ping.h"
|
||||||
#include "configHandler.h"
|
#include "configHandler.h"
|
||||||
|
|
||||||
|
const char* APPID = "1407025303779278980";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void handleDiscordReady(const DiscordUser* connectedUser)
|
||||||
|
{
|
||||||
|
printf("\nDiscord: connected to user %s#%s - %s\n",
|
||||||
|
connectedUser->username,
|
||||||
|
connectedUser->discriminator,
|
||||||
|
connectedUser->userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleDiscordDisconnected(int errcode, const char* message)
|
||||||
|
{
|
||||||
|
printf("\nDiscord: disconnected (%d: %s)\n", errcode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleDiscordError(int errcode, const char* message)
|
||||||
|
{
|
||||||
|
printf("\nDiscord: error (%d: %s)\n", errcode, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void discordInit()
|
||||||
|
{
|
||||||
|
DiscordEventHandlers handlers;
|
||||||
|
memset(&handlers, 0, sizeof(handlers));
|
||||||
|
handlers.ready = handleDiscordReady;
|
||||||
|
handlers.disconnected = handleDiscordDisconnected;
|
||||||
|
handlers.errored = handleDiscordError;
|
||||||
|
Discord_Initialize(APPID, &handlers, 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updatePresence() {
|
||||||
|
char buffer[256];
|
||||||
|
DiscordRichPresence presence;
|
||||||
|
memset(&presence, 0, sizeof(presence));
|
||||||
|
sprintf(buffer, "Idle"); // Change to snprintf
|
||||||
|
presence.details = buffer;
|
||||||
|
presence.activity_type = DISCORD_ACTIVITY_TYPE_LISTENING;
|
||||||
|
Discord_UpdatePresence(&presence);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
configHandler_config_t* configObj = NULL;
|
configHandler_config_t* configObj = NULL;
|
||||||
int checkConfigFile();
|
int checkConfigFile();
|
||||||
int validateConnection();
|
int validateConnection();
|
||||||
@@ -44,6 +92,10 @@ int main(int argc, char** argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Launch Discord RPC
|
||||||
|
discordInit();
|
||||||
|
updatePresence();
|
||||||
|
|
||||||
// Launch QT frontend
|
// Launch QT frontend
|
||||||
qt_gui_entry(argc, argv);
|
qt_gui_entry(argc, argv);
|
||||||
|
|
||||||
@@ -113,6 +165,7 @@ int validateConnection() {
|
|||||||
printf("Code %d - %s\n", OSS_ping_struct->errorCode, OSS_ping_struct->errorMessage);
|
printf("Code %d - %s\n", OSS_ping_struct->errorCode, OSS_ping_struct->errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: A little verbose to avoid making another variable to hold error code after freeing structs
|
||||||
if (!OSS_ping_struct->error) {
|
if (!OSS_ping_struct->error) {
|
||||||
opensubsonic_ping_struct_free(&OSS_ping_struct);
|
opensubsonic_ping_struct_free(&OSS_ping_struct);
|
||||||
opensubsonic_httpClient_URL_cleanup(&pingUrl);
|
opensubsonic_httpClient_URL_cleanup(&pingUrl);
|
||||||
|
|||||||
Reference in New Issue
Block a user