From 590fb2350f35fc37b1ca12c04984849ec05d851a Mon Sep 17 00:00:00 2001 From: XorTroll Date: Fri, 1 Nov 2019 21:22:45 +0100 Subject: [PATCH] Improve QDaemon, QForegroundViewer and settings menu --- .../Include/ui/ui_SettingsMenuLayout.hpp | 3 +- .../RomFs/default/ui/SettingEditable.png | Bin 0 -> 4311 bytes .../RomFs/default/ui/SettingNoEditable.png | Bin 0 -> 3777 bytes .../RomFs/default/ui/Suspended.png | Bin 0 -> 1480 bytes .../Source/ui/ui_SettingsMenuLayout.cpp | 13 ++- .../ScreenshotForm.Designer.cs | 18 ++-- .../QForegroundViewer/ScreenshotForm.cs | 1 - .../QForegroundViewer/ToolboxForm.cs | 1 + .../ViewerMainForm.Designer.cs | 4 +- .../QForegroundViewer/ViewerMainForm.cs | 15 ++- README.md | 16 +--- SystemAppletQDaemon/Source/Main.cpp | 90 ++++++++++-------- Themes.md | 10 +- 13 files changed, 97 insertions(+), 74 deletions(-) create mode 100644 LibraryAppletQMenu/RomFs/default/ui/SettingEditable.png create mode 100644 LibraryAppletQMenu/RomFs/default/ui/SettingNoEditable.png create mode 100644 LibraryAppletQMenu/RomFs/default/ui/Suspended.png diff --git a/LibraryAppletQMenu/Include/ui/ui_SettingsMenuLayout.hpp b/LibraryAppletQMenu/Include/ui/ui_SettingsMenuLayout.hpp index a042e2b..5ff369f 100644 --- a/LibraryAppletQMenu/Include/ui/ui_SettingsMenuLayout.hpp +++ b/LibraryAppletQMenu/Include/ui/ui_SettingsMenuLayout.hpp @@ -13,9 +13,10 @@ namespace ui PU_SMART_CTOR(SettingsMenuLayout) void OnInput(u64 down, u64 up, u64 held, pu::ui::Touch pos); void Reload(); - void PushSettingItem(std::string name, std::string value_display, u32 id); + void PushSettingItem(std::string name, std::string value_display, int id); void setting_Click(u32 id); private: + pu::ui::elm::TextBlock::Ref infoText; pu::ui::elm::Menu::Ref settingsMenu; }; } \ No newline at end of file diff --git a/LibraryAppletQMenu/RomFs/default/ui/SettingEditable.png b/LibraryAppletQMenu/RomFs/default/ui/SettingEditable.png new file mode 100644 index 0000000000000000000000000000000000000000..ada6464b47a5199214f876fb4b9c62ed44e9423e GIT binary patch literal 4311 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 FV1ha88B+iN literal 0 HcmV?d00001 diff --git a/LibraryAppletQMenu/RomFs/default/ui/SettingNoEditable.png b/LibraryAppletQMenu/RomFs/default/ui/SettingNoEditable.png new file mode 100644 index 0000000000000000000000000000000000000000..3db0f58a9f1819cbd36e700f19def58185286440 GIT binary patch literal 3777 zcmV;y4nFaTP)c0yXmsq1rGa$-W0 zp2lfT1=s|Tphr${X#$oo4~a|>HU`Nw#-I(fR0d(2 znQMcv>jyuZ0ssoI<0U{no(oq6W#0=$D+nXlW`$HylpVY3hml6D zqb8@DONlTX&YM5z+_h=Yn?)v|<0?OV8@~uK1Hc%3j0^k!~eY0T*;D=0I-*af^ zmh)~hYMQ3LYbKVG$xR?ExcD(Mi!UAAarZxYamuqG^)2n+1VJ0)t2`J_Dk?hmYt64) z+0Zmi^q7gI%-9O>wO)O4iDO~bY7Zx}`tTYMuLm$^j3lRwVaz|=(VUTW#*-ioTOXLk z!h91z+$QOZAnfYe-u%y3eo?ROUI2r>4dByWeDQ%KgEk#(YwEo6i-yhjP2o`JE-?NE zz+@{UM7a0B_U0B@C%g&L+Ws^HOPrTRuaJrMIcoaZH{SRd#pm~Y6O1hY6fb`G%(JQy zTKm|2-{`Gx+5P(vbT=5Q07M<;&w=^+t{ofSkttkSkX2hdZXv-(Wo$6;YXS5zaFcBL zLBc>kKra*c3y>R${##dD^PkIf*CG))vnhLO*WK+or)7YZ;< z1I#7>fJi_H1!^b+H5^7b5=AIl1|cSXbk8hqlj-241gUTB_$t7U%H(y6X_^>Lr!bsO zAwMzq4j+e-y|zo!M%?6b-FDxxX=jyC#6J=cbDP%ZdxA~mH z%t)Q@$Jvv|kseHf-Bt-3+v&k1dV7u|HPGj)?Xe*6rWGyi^W5ZdB}jwT@i7Lz=FTnW zZ?$jH$wco}J&#{^h!?@6Q4w=*i z|4q9fR$hroQ)@xNEaShOQ8FLz*0j7`LPs@Z-MYOIW_MN32@J--+0(ysF#sStG>GKc z(?PYA*TnVsdM61T36ieNZ2<5QPcD53#$aDBhBL*pt8+M$MzZfrFvbbn)@0#i7(dKk_+Ou{Jw0V0sgTR{^{O zrYs2M0K&eNz>H`-;oS`37p#cI2e&ubq1pJ=UJm=o)LBU&d^`fcfZ~L!9hg|iv3vX|% z36c3j05{7P9EwCSb*Al{?lKtozN#p9?$~p#s;mJ3ShQ^Q4G`iLNIr9Q?R1nS%B>R-y`l)Qe80Bg z*D_@QKFmW7>}dMFsTiLGFf?8oFHIEzPk9vs0G@m5yT1VVY1#bw5!+|@!CaBP*^3x} zPZPuF>8dlZSkm=0mN)5P`OKFi1U({~SJ!QxfsxiU&GU@c7eVyt*;%ld)93};(cXBR z`;(8(cv&{{l~m*gUjiW2581v{!rMsh12aBg8iwU=KGTpsqkl}(G~WVB-QC>=fMYUw z?Vf?n@%vCW_#y}sSw@53-#6tJ0{mZ`AUT_C6KEvzCnD~PAOyCyBRSe-NGfS*l%?8v z2an*(c36L+y#|dt!Wu0_ZgfpV0UW9k)1`8e?N8;)YMVcONC=j*QK85c!;JY-8OMhJ zma-`nn+ibiWn+LZf(Q(qghj1ZRq5dCoW);R?c2ef#b0UsB!F2mc~#YBmd-dKWA{pY z5yVKx6#%L6zE{KY(QwlgtEDr4$QC!q=2b%0&p=>bc58SJovdtazexaH_~1y}hsdS| zk?cDwTSSf&%s+DYv3F$+0KlzxtiGBc-h|{@N!8S8h?QI4g+t)Zw31!tWdGIpHYBOn zv?v?#HUc)lrl#qIJbF*c|DFW=Oi7k~=EpyNC?}Ku^PgWA(W{1!0+7BZYufCOKnXbt zF8*9GY3crZn|fr*k!rG5YV99~5r3J0CMP!3P#CIBmA8U{oAm1819f$Eu8q{y)rIw{ zY!^I;p@zdw#Q=a$8-oA4zGe3pWXf_?LmC_Rg$lKUEhcCSxja%mG|-Qf$4vvwc)<** zw?BXA+rM#={&UM3X0cG7gom{d04T4nK}D5iFk∋GLPb=5BLyouFeuR<+)LEkQX5 z$x~B$p>VO;^1Otb1^6LSXy17K%B^>-zM5FM6U6J_aUTFcsGU6zYDjXAIpL>5n74md zyXUmCr6NX(7B5rOeJ6e0N;*QN8<@h zo;Jg)nLZFL@7mtv&| z;+`Xq-?!c}{BJ49;T`w931aDG&+#Zrlp|gd$PKW*5UZ%Pot3+V0bNnhWS7o%QkTyg zf5(!`o>ok%sYN7acSXv?6N$z!smA{rEPzMsF5$VD&YJJtzd0!w(wC`>3lXYorz7NF zr|FqcB#P>*W`L|WsJn)N{#-%VoTPPjr0wlFkAd-;C$GjTTnN-mpNViZ&^rhm5h*J} z&GeapTqr=G*6-cF+0nLtN2PanFENj+>1A%udO=`($Av)vFYufXK1W(70)W4xAm zYqsUw<5C=ZaO{O6JqvDGJRgMXNG8!Fk)L7v>Ab1`{ar<05){BH9vLfhjr`s zlqKSNJrmsx`}6~`?|I_+r6Ncc)!`YwPP*7 zmmaD~0{kcxJk+IabhR1l;-$(OfG_&tn+*dDdXN-lZP z`$#Wbdtm1lPe+Y?cxa~j*7nT+7J|jU#?-R?UjIpR)wYi1G`bcO6sHPGtSJBKb9L(jpD1Uw@p7O%2?L>tY~SUCkSf=*q3`m rnDKf>&F=GZO14Ca5+zEMC|3R-0`mKrX(n<<00000NkvXXu0mjfqqHn2 literal 0 HcmV?d00001 diff --git a/LibraryAppletQMenu/RomFs/default/ui/Suspended.png b/LibraryAppletQMenu/RomFs/default/ui/Suspended.png new file mode 100644 index 0000000000000000000000000000000000000000..968a804023fe15d8e85f7f14e7ef3d537f4c3086 GIT binary patch literal 1480 zcmeAS@N?(olHy`uVBq!ia0y~yVAKF%4mP03YxW#TAjMc5RtvY3H^?;r>>?wFYUmVtpa*3-o?q$2L^orQhT?h*}w`JxdL5fLl7 z_;fuU*tskf3kgj~xVI#cv9hg&t>qh|mZ+Er5V(1zKarm2Wjs6oZSj(eG16Ti6^^Xh&w`?}MgZr&GMVc##iL+^BYz59ZH7G)21>CFEt+xYA4jmFoTYQB}Tyt=!Q z`FiTlH}5&F{NDJ_PM#?|>D-?=f0s^UfA#JA<@Swxt?ZfB9a)|HZThW3Hq*T_*+1>M zRnA7vH{O3|nnUlTbE|)@Ki}WL{r%UBpHIu?I{NA#`}MqrBW8u=zG2VMcocD_QV^>>=+uxII zC0~DxFpjz3^Yv@Qfw<3Am-gJe!*g*@>Zv{22Y(x${{LI{+%1Q>e*YQwY)fV={y!}l QSo$(}y85}Sb4q9e0Cl+R2mk;8 literal 0 HcmV?d00001 diff --git a/LibraryAppletQMenu/Source/ui/ui_SettingsMenuLayout.cpp b/LibraryAppletQMenu/Source/ui/ui_SettingsMenuLayout.cpp index b0b2266..53aee6b 100644 --- a/LibraryAppletQMenu/Source/ui/ui_SettingsMenuLayout.cpp +++ b/LibraryAppletQMenu/Source/ui/ui_SettingsMenuLayout.cpp @@ -38,9 +38,16 @@ namespace ui { this->SetBackgroundImage(cfg::ProcessedThemeResource(theme, "ui/Background.png")); + pu::ui::Color textclr = pu::ui::Color::FromHex(qapp->GetUIConfigValue("text_color", "#e1e1e1ff")); pu::ui::Color menufocusclr = pu::ui::Color::FromHex(qapp->GetUIConfigValue("menu_focus_color", "#5ebcffff")); pu::ui::Color menubgclr = pu::ui::Color::FromHex(qapp->GetUIConfigValue("menu_bg_color", "#0094ffff")); + this->infoText = pu::ui::elm::TextBlock::New(0, 100, "Browse and/or edit settings here."); + this->infoText->SetColor(textclr); + this->infoText->SetHorizontalAlign(pu::ui::elm::HorizontalAlign::Center); + qapp->ApplyConfigForElement("settings_menu", "info_text", this->infoText); + this->Add(this->infoText); + this->settingsMenu = pu::ui::elm::Menu::New(200, 160, 880, menubgclr, 100, 4); this->settingsMenu->SetOnFocusColor(menufocusclr); qapp->ApplyConfigForElement("settings_menu", "settings_menu_item", this->settingsMenu); @@ -55,15 +62,19 @@ namespace ui char consolename[SET_MAX_NICKNAME_SIZE] = {}; setsysGetDeviceNickname(consolename); this->PushSettingItem("Console nickname", EncodeForSettings(consolename), 0); + TimeLocationName loc = {}; + timeGetDeviceLocationName(&loc); + this->PushSettingItem("Console timezone location", EncodeForSettings(loc.name), -1); this->PushSettingItem("PC viewer USB enabled", EncodeForSettings(config.viewer_usb_enabled), 1); this->PushSettingItem("Homebrew-as-application 'flog' takeover enabled", EncodeForSettings(config.system_title_override_enabled), 2); } - void SettingsMenuLayout::PushSettingItem(std::string name, std::string value_display, u32 id) + void SettingsMenuLayout::PushSettingItem(std::string name, std::string value_display, int id) { pu::ui::Color textclr = pu::ui::Color::FromHex(qapp->GetUIConfigValue("text_color", "#e1e1e1ff")); auto itm = pu::ui::elm::MenuItem::New(name + ": " + value_display); itm->AddOnClick(std::bind(&SettingsMenuLayout::setting_Click, this, id)); + itm->SetIcon(cfg::ProcessedThemeResource(theme, "ui/Setting" + std::string((id < 0) ? "No" : "") + "Editable.png")); itm->SetColor(textclr); this->settingsMenu->AddItem(itm); } diff --git a/QForegroundViewer/QForegroundViewer/ScreenshotForm.Designer.cs b/QForegroundViewer/QForegroundViewer/ScreenshotForm.Designer.cs index 52b11c1..4c29c8d 100644 --- a/QForegroundViewer/QForegroundViewer/ScreenshotForm.Designer.cs +++ b/QForegroundViewer/QForegroundViewer/ScreenshotForm.Designer.cs @@ -49,7 +49,7 @@ this.groupBox1.Size = new System.Drawing.Size(200, 58); this.groupBox1.TabIndex = 1; this.groupBox1.TabStop = false; - this.groupBox1.Text = "Available screenshots"; + this.groupBox1.Text = "Available screenshot stack"; // // ScreenshotList // @@ -83,7 +83,7 @@ this.groupBox2.Size = new System.Drawing.Size(200, 56); this.groupBox2.TabIndex = 3; this.groupBox2.TabStop = false; - this.groupBox2.Text = "Image format"; + this.groupBox2.Text = "Image save format"; // // FormatList // @@ -99,17 +99,17 @@ // // SaveButton // - this.SaveButton.Location = new System.Drawing.Point(12, 229); + this.SaveButton.Location = new System.Drawing.Point(12, 270); this.SaveButton.Name = "SaveButton"; - this.SaveButton.Size = new System.Drawing.Size(153, 55); + this.SaveButton.Size = new System.Drawing.Size(221, 44); this.SaveButton.TabIndex = 4; - this.SaveButton.Text = "Save"; + this.SaveButton.Text = "Save as..."; this.SaveButton.UseVisualStyleBackColor = true; this.SaveButton.Click += new System.EventHandler(this.SaveButton_Click); // // RefreshButton // - this.RefreshButton.Location = new System.Drawing.Point(12, 153); + this.RefreshButton.Location = new System.Drawing.Point(12, 185); this.RefreshButton.Name = "RefreshButton"; this.RefreshButton.Size = new System.Drawing.Size(172, 29); this.RefreshButton.TabIndex = 5; @@ -119,9 +119,9 @@ // // ClipboardButton // - this.ClipboardButton.Location = new System.Drawing.Point(13, 189); + this.ClipboardButton.Location = new System.Drawing.Point(12, 220); this.ClipboardButton.Name = "ClipboardButton"; - this.ClipboardButton.Size = new System.Drawing.Size(171, 29); + this.ClipboardButton.Size = new System.Drawing.Size(221, 44); this.ClipboardButton.TabIndex = 6; this.ClipboardButton.Text = "Copy to clipboard"; this.ClipboardButton.UseVisualStyleBackColor = true; @@ -131,7 +131,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 333); + this.ClientSize = new System.Drawing.Size(784, 331); this.Controls.Add(this.ClipboardButton); this.Controls.Add(this.RefreshButton); this.Controls.Add(this.SaveButton); diff --git a/QForegroundViewer/QForegroundViewer/ScreenshotForm.cs b/QForegroundViewer/QForegroundViewer/ScreenshotForm.cs index 003185d..527961e 100644 --- a/QForegroundViewer/QForegroundViewer/ScreenshotForm.cs +++ b/QForegroundViewer/QForegroundViewer/ScreenshotForm.cs @@ -98,7 +98,6 @@ namespace QForegroundViewer private void ClipboardButton_Click(object sender, EventArgs e) { Clipboard.SetImage(ScreenshotBox.Image); - MessageBox.Show("Selected screenshot copied to clipboard."); } } } diff --git a/QForegroundViewer/QForegroundViewer/ToolboxForm.cs b/QForegroundViewer/QForegroundViewer/ToolboxForm.cs index 47542c5..083962d 100644 --- a/QForegroundViewer/QForegroundViewer/ToolboxForm.cs +++ b/QForegroundViewer/QForegroundViewer/ToolboxForm.cs @@ -20,6 +20,7 @@ namespace QForegroundViewer main = Main; IncrementNumeric.Increment = 0.1m; IncrementNumeric.Minimum = 0.1m; + IncrementNumeric.Value = 1.0m; } private void AboutButton_Click(object sender, EventArgs e) diff --git a/QForegroundViewer/QForegroundViewer/ViewerMainForm.Designer.cs b/QForegroundViewer/QForegroundViewer/ViewerMainForm.Designer.cs index 959a50c..309b08a 100644 --- a/QForegroundViewer/QForegroundViewer/ViewerMainForm.Designer.cs +++ b/QForegroundViewer/QForegroundViewer/ViewerMainForm.Designer.cs @@ -39,7 +39,7 @@ this.CaptureBox.Location = new System.Drawing.Point(0, 0); this.CaptureBox.Margin = new System.Windows.Forms.Padding(0); this.CaptureBox.Name = "CaptureBox"; - this.CaptureBox.Size = new System.Drawing.Size(624, 321); + this.CaptureBox.Size = new System.Drawing.Size(1280, 720); this.CaptureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; this.CaptureBox.TabIndex = 0; this.CaptureBox.TabStop = false; @@ -48,7 +48,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(624, 321); + this.ClientSize = new System.Drawing.Size(1280, 720); this.Controls.Add(this.CaptureBox); this.Name = "ViewerMainForm"; this.Text = "uLaunch - Foreground display viewer"; diff --git a/QForegroundViewer/QForegroundViewer/ViewerMainForm.cs b/QForegroundViewer/QForegroundViewer/ViewerMainForm.cs index 84a0616..60349d7 100644 --- a/QForegroundViewer/QForegroundViewer/ViewerMainForm.cs +++ b/QForegroundViewer/QForegroundViewer/ViewerMainForm.cs @@ -60,6 +60,16 @@ namespace QForegroundViewer base.OnClosing(e); } + protected override void OnShown(EventArgs e) + { + if(USB == null) + { + MessageBox.Show("Unable to connect to uLaunch via USB-C cable.", "Unable to connect"); + Environment.Exit(Environment.ExitCode); + } + base.OnShown(e); + } + public void USBThreadMain() { while(RefreshCapture()); @@ -67,11 +77,6 @@ namespace QForegroundViewer public bool RefreshCapture() { - if(USB == null) - { - MessageBox.Show("Unable to connect to uLaunch via USB-C cable.", "Unable to connect"); - Environment.Exit(Environment.ExitCode); - } try { USB.ReadPipe(0x81, CaptureBlocks[0], CaptureBlocks[0].Length, out _, IntPtr.Zero); diff --git a/README.md b/README.md index 7e458ac..9ce2f6b 100644 --- a/README.md +++ b/README.md @@ -61,15 +61,15 @@ This is the amount of features uLaunch contains, compared to the original HOME m - **User password** support! (up to 15 characters) -> Note: some classic HOME menu functionality (eShop, friends...) isn't implemented here. This reimplementation is mainly homebrew-orienteed, so it will lack some classic functionality. +> Note: some classic HOME menu functionality (eShop, friends...) isn't (and probably won't be) implemented here. This reimplementation is mainly homebrew-orienteed, so it will lack some classic functionality which isn't specially worth it to reverse and implement. ## Disclaimer -### Homebrew as applications +### Homebrew-as-application 'flog' takeover -uLaunch launches homebrew present (added) to main menu as an application, taking advantage of **flog**'s built-in application title, which was stubbed but not removed, thus it's content can be overriden via LayeredFS and launched. +uLaunch launches homebrew present (added) to main menu as an application, taking advantage of the system's '**flog**' built-in application title, which was stubbed but not removed, thus it's content can be overriden via LayeredFS and launched. -Since launching this title should be impossible, it might involve ban risk, so **use it at your own risk**. uLaunch **warns on launching titles this way**. +Since launching this title should be impossible, it might involve ban risk. uLaunch has this option **disabled by default**, so enable and use it **use it at your own risk**. ## Project and subprojects @@ -79,13 +79,7 @@ uLaunch is split, as mentioned above, into several sub-projects: > This sub-project replaces qlaunch, aka title 0100000000001000. -This is the technically actual qlaunch reimplementation. However, to avoid memory issues it does not use any kind of UI (except console for development debug, which is removed for releases), and thus it uses 8MB of heap, while official HOME menu uses 56MB. - -Instead, it uses [QMenu custom library applet](#qmenu-libraryappletqmenu) (launches and communicates with it) in order to display a proper menu UI. - -But, if all the functionality is handled by QMenu, why is this daemon process necessary? Well, mainly since the system applet process has a lot of unique code it's the only one who can use, specially, related to title launching, focus managing... - -**TL;DR**: this is a simple daemon process which stays communicated with QMenu to perform tasks it is asked to so, specially with code it is the only one that can access. +This is the technically actual qlaunch reimplementation. In fact, it is used as a back-end for the project, which just does what the actual menu (QMenu) tells it to do. This had to be like that, since qlaunch is the only one who can access certain essential functionality like title launching, so QMenu needs to access it, so it communicates with this back-end to execute it and to obtain its outcome. ### QMenu (LibraryAppletQMenu) diff --git a/SystemAppletQDaemon/Source/Main.cpp b/SystemAppletQDaemon/Source/Main.cpp index 5c50f30..663a869 100644 --- a/SystemAppletQDaemon/Source/Main.cpp +++ b/SystemAppletQDaemon/Source/Main.cpp @@ -37,46 +37,6 @@ void CommonSleepHandle() appletStartSleepSequence(true); } -void HandleGeneralChannel() -{ - AppletStorage sams_st; - auto rc = appletPopFromGeneralChannel(&sams_st); - if(R_SUCCEEDED(rc)) - { - os::SystemAppletMessage sams = {}; - rc = appletStorageRead(&sams_st, 0, &sams, sizeof(os::SystemAppletMessage)); - appletStorageClose(&sams_st); - if(R_SUCCEEDED(rc)) - { - if(sams.magic == os::SAMSMagic) - { - os::GeneralChannelMessage msg = (os::GeneralChannelMessage)sams.message; - switch(msg) - { - case os::GeneralChannelMessage::Shutdown: - { - appletStartShutdownSequence(); - break; - } - case os::GeneralChannelMessage::Reboot: - { - appletStartRebootSequence(); - break; - } - case os::GeneralChannelMessage::Sleep: - { - appletStartSleepSequence(true); - break; - } - default: - break; - } - } - } - } - svcSleepThread(100000000L); -} - void HandleHomeButton() { bool used_to_reopen_menu = false; @@ -102,6 +62,51 @@ void HandleHomeButton() } } +void HandleGeneralChannel() +{ + AppletStorage sams_st; + auto rc = appletPopFromGeneralChannel(&sams_st); + if(R_SUCCEEDED(rc)) + { + os::SystemAppletMessage sams = {}; + rc = appletStorageRead(&sams_st, 0, &sams, sizeof(os::SystemAppletMessage)); + appletStorageClose(&sams_st); + if(R_SUCCEEDED(rc)) + { + if(sams.magic == os::SAMSMagic) + { + os::GeneralChannelMessage msg = (os::GeneralChannelMessage)sams.message; + switch(msg) + { + case os::GeneralChannelMessage::HomeButton: // Usually this doesn't happen, HOME is detected by applet messages...? + { + HandleHomeButton(); + break; + } + case os::GeneralChannelMessage::Shutdown: + { + appletStartShutdownSequence(); + break; + } + case os::GeneralChannelMessage::Reboot: + { + appletStartRebootSequence(); + break; + } + case os::GeneralChannelMessage::Sleep: + { + appletStartSleepSequence(true); + break; + } + default: // We don't have anything special to do for the rest + break; + } + } + } + } + svcSleepThread(100000000L); +} + void HandleAppletMessage() { u32 nmsg = 0; @@ -359,7 +364,7 @@ namespace qdaemon { app_buf = new u8[RawRGBAScreenBufferSize](); - db::Mount(); + db::Mount(); // Keep qlaunch's savedata always mounted to avoid others to access it. fs::CreateDirectory(Q_BASE_DB_DIR); fs::CreateDirectory(Q_BASE_SD_DIR); fs::CreateDirectory(Q_ENTRIES_PATH); @@ -430,6 +435,8 @@ namespace qdaemon void DaemonServiceMain(void *arg) { + // TODO: restrict service access to QMenu? + static auto server = WaitableManager(2); server.AddWaitable(new ServiceServer(AM_QDAEMON_SERVICE_NAME, 0x10)); server.Process(); @@ -469,6 +476,7 @@ namespace qdaemon } } +// QDaemon handles basic qlaunch functionality and serves as a back-end for uLaunch, communicating with QMenu front-end when neccessary. int main() { qdaemon::Initialize(); diff --git a/Themes.md b/Themes.md index b57747c..ff36cd7 100644 --- a/Themes.md +++ b/Themes.md @@ -153,6 +153,12 @@ Can be customized via files in `/ui`. - `ui/Banner{type}.png` -> Different 1280x135 PNG banners for menu item types (BannerFolder, BannerHomebrew or BannerInstalled) +## Settings menu + +- `ui/SettingEditable.png` -> 100x100 PNG for settings which can be edited. + +- `ui/SettingNoEditable.png` -> 100x100 PNG for settings which cannot be edited (thus can only be seen). + ### Top menu The top menu is the small bar shown at the top of the main menu, whose background and icons are customizable. @@ -161,6 +167,4 @@ All the menu icons ({...}Icon.png) are 50x50 icons, except battery ones (Battery - `ui/TopMenu.png` -> Background of menu (1220x85 PNG) -- Icons in top menu (50x50 PNGs): ConnectionIcon, NoConnectionIcon, SettingsIcon, ThemesIcon, WebIcon - -> *TODO: more menu icons* \ No newline at end of file +- Icons in top menu (50x50 PNGs): ConnectionIcon, NoConnectionIcon, SettingsIcon, ThemesIcon, WebIcon \ No newline at end of file