You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

291 lines
10 KiB

/******************************************************************************************\
* *
* main.cpp *
* *
* Main function for OpenAuraSDK GUI project *
* *
\******************************************************************************************/
#include "ResourceManager.h"
#include "NetworkClient.h"
#include "NetworkServer.h"
#include "OpenRGB.h"
#include "ProfileManager.h"
#include "RGBController.h"
#include "i2c_smbus.h"
#include "LogManager.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include "OpenRGBDialog2.h"
using namespace std::chrono_literals;
/*-------------------------------------------------------------*\
| Command line functionality and return flags |
\*-------------------------------------------------------------*/
extern unsigned int cli_pre_detection(int argc, char *argv[]);
extern unsigned int cli_post_detection(int argc, char *argv[]);
enum
{
RET_FLAG_PRINT_HELP = 1,
RET_FLAG_START_GUI = 2,
RET_FLAG_I2C_TOOLS = 4,
RET_FLAG_START_MINIMIZED = 8,
RET_FLAG_NO_DETECT = 16,
RET_FLAG_CLI_POST_DETECTION = 32,
RET_FLAG_START_SERVER = 64,
RET_FLAG_NO_AUTO_CONNECT = 128,
};
/******************************************************************************************\
* *
* InitializeTimerResolution (Win32) *
* *
* On Windows, the default timer resolution is 15.6ms. For higher accuracy delays, *
* the timer resolution should be set to a shorter interval. The shortest interval *
* that can be set is 0.5ms. *
* *
\******************************************************************************************/
#ifdef _WIN32
typedef unsigned int NTSTATUS;
typedef NTSTATUS (*NTSETTIMERRESOLUTION)(ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
void InitializeTimerResolution()
{
NTSETTIMERRESOLUTION NtSetTimerResolution;
HMODULE NtDllHandle;
ULONG CurrentResolution;
NtDllHandle = LoadLibrary("ntdll.dll");
NtSetTimerResolution = (NTSETTIMERRESOLUTION)GetProcAddress(NtDllHandle, "NtSetTimerResolution");
NtSetTimerResolution(5000, TRUE, &CurrentResolution);
}
void InitializeTimerResolutionThreadFunction()
{
while(1)
{
InitializeTimerResolution();
std::this_thread::sleep_for(500ms);
}
}
#endif
void WaitWhileServerOnline(NetworkServer* srv)
{
while (srv->GetOnline())
{
std::this_thread::sleep_for(1s);
};
}
/******************************************************************************************\
* *
* AttemptLocalConnection *
* *
* Attempts an SDK connection to the local server. Returns true if success *
* *
\******************************************************************************************/
bool AttemptLocalConnection()
{
bool success = false;
NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers());
std::string titleString = "OpenRGB ";
titleString.append(VERSION_STRING);
client->SetName(titleString.c_str());
client->StartClient();
for(int timeout = 0; timeout < 10; timeout++)
{
if(client->GetConnected())
{
break;
}
std::this_thread::sleep_for(5ms);
}
if(!client->GetConnected())
{
client->StopClient();
delete client;
client = NULL;
}
else
{
ResourceManager::get()->RegisterNetworkClient(client);
success = true;
/*-----------------------------------------------------*\
| Wait up to 5 seconds for the client connection to |
| retrieve all controllers |
\*-----------------------------------------------------*/
for(int timeout = 0; timeout < 1000; timeout++)
{
if(client->GetOnline())
{
break;
}
std::this_thread::sleep_for(5ms);
}
}
return success;
}
/******************************************************************************************\
* *
* main *
* *
* Main function. Detects busses and Aura controllers, then opens the main window *
* *
\******************************************************************************************/
int main(int argc, char* argv[])
{
#ifdef _WIN32
/*---------------------------------------------------------*\
| Windows only - Attach console output |
\*---------------------------------------------------------*/
if (AttachConsole(ATTACH_PARENT_PROCESS))
{
/*---------------------------------------------------------*\
| We are running under some terminal context; otherwise |
| leave the GUI and CRT alone |
\*---------------------------------------------------------*/
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
}
/*---------------------------------------------------------*\
| Windows only - Start timer resolution correction thread |
\*---------------------------------------------------------*/
std::thread * InitializeTimerResolutionThread;
InitializeTimerResolutionThread = new std::thread(InitializeTimerResolutionThreadFunction);
InitializeTimerResolutionThread->detach();
#endif
/*---------------------------------------------------------*\
| Process command line arguments before detection |
\*---------------------------------------------------------*/
unsigned int ret_flags = cli_pre_detection(argc, argv);
/*---------------------------------------------------------*\
| Perform local connection and/or hardware detection if not |
| disabled from CLI |
\*---------------------------------------------------------*/
if(!(ret_flags & RET_FLAG_NO_AUTO_CONNECT))
{
printf("Attempting to connect to local OpenRGB server.\r\n");
if(!AttemptLocalConnection())
{
printf("Local OpenRGB server unavailable.\r\n");
}
else
{
printf("Local OpenRGB server connected, running in client mode\r\n");
ResourceManager::get()->DisableDetection();
}
}
/*---------------------------------------------------------*\
| Perform hardware detection if not disabled from CLI |
\*---------------------------------------------------------*/
if(!(ret_flags & RET_FLAG_NO_DETECT))
{
if(ResourceManager::get()->GetDetectionEnabled())
{
printf("Running standalone.\r\n");
}
ResourceManager::get()->DetectDevices();
}
/*---------------------------------------------------------*\
| Start the server if requested from CLI (this must be done |
| after attempting local connection!) |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_START_SERVER)
{
ResourceManager::get()->GetServer()->StartServer();
if(!ResourceManager::get()->GetServer()->GetOnline())
{
printf("Server failed to start\r\n");
}
}
/*---------------------------------------------------------*\
| Process command line arguments after detection only if the|
| pre-detection parsing indicated it should be run |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_CLI_POST_DETECTION)
{
ret_flags |= cli_post_detection(argc, argv);
}
/*---------------------------------------------------------*\
| If the command line parser indicates that the GUI should |
| run, or if there were no command line arguments, start the|
| GUI. |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_START_GUI)
{
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
Ui::OpenRGBDialog2 dlg;
if(ret_flags & RET_FLAG_I2C_TOOLS)
{
dlg.AddI2CToolsPage();
}
dlg.AddClientTab();
if(ret_flags & RET_FLAG_START_MINIMIZED)
{
dlg.hide();
}
else
{
dlg.show();
}
return a.exec();
}
else
{
if(ret_flags & RET_FLAG_START_SERVER)
{
if(!ResourceManager::get()->GetServer()->GetOnline())
{
return 1;
}
else
{
WaitWhileServerOnline(ResourceManager::get()->GetServer());
}
}
else
{
return 0;
}
}
}