seerge / g-helper

Lightweight Armoury Crate alternative for Asus laptops and ROG Ally. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models
https://g-helper.com
GNU General Public License v3.0
7.59k stars 266 forks source link

Zephyrus keyboard function #574

Closed AnhPham1408 closed 1 year ago

AnhPham1408 commented 1 year ago

Since the zephyrus duo keyboard layout is different from others model, Is it possible to keep original function or remap the two keys between armoury key and the power button (the left is to change the turn on/off second screen, other is to change between arrow, pgup/pgdn).

For the turn on/off screen, I can do that with the Fn + F9 (windows + P) between extend and PC screen only.

Other functions are working perfectly, really appreciate the project.

image

seerge commented 1 year ago

@AnhPham1408 hello,

Try to press those keys (with asus optimizations serive disabled and g-helper started) and then look at %appdata%/g-helper/log.txt Each keypress should trigger an event in the log.

I need event or keys IDs from there do process them somehow

AnhPham1408 commented 1 year ago

6/8/2023 9:38:03 PM: Key: 106 6/8/2023 9:38:05 PM: Key: 75

Key 106 is for turning on/off second display. Key 75 is for changing between arrows and pgup/padn Here is the log file. log.txt

seerge commented 1 year ago

@AnhPham1408 oke, thanks. But since both actions are non standard, i need to know how laptop does them

Can you crate a dump as explained here and upload it here ?

Download ACPICA tools from here: https://acpica.org/downloads/binary-tools Extract, run acpidump tool, then you can use the other tool called iasl to decompile resulting files to something that humans can read.

Both tools include comprehensive help messages, but if all you want to achieve is dumping your DSDT and decompiling it, run acpidump.exe -b to dump them all to .dat files. They'll be placed in the location you ran the tool from. Then run iasl.exe dsdt.dat and the decompiled ACPI table will be created as dsdt.dsl.

AnhPham1408 commented 1 year ago

Since I don't know if I need to enable the ASUSoptimization service or not, I run two version. ASUSoptimization disable: OpDisable.zip

ASUSoptimization enable: OpEnable.zip

seerge commented 1 year ago

@AnhPham1408 hello, thanks. I looked at section that is responsible for hotkey "actions"

                   If ((IIA0 == 0x00100021))
                    {
                        If ((IIA1 == 0x6C))
                        {
                            ^^PCI0.SBRG.EC0._Q0A ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x88))
                        {
                            ^^PCI0.SBRG.EC0._Q0B ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0xC5))
                        {
                            ^^PCI0.SBRG.EC0.KBLD ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0xC4))
                        {
                            ^^PCI0.SBRG.EC0.KBLU ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0xC7))
                        {
                            ^^PCI0.SBRG.EC0.KBLU ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x10))
                        {
                            ^^PCI0.SBRG.EC0._Q0E ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x20))
                        {
                            ^^PCI0.SBRG.EC0._Q0F ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x35))
                        {
                            ^^PCI0.SBRG.EC0._Q10 ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x6B))
                        {
                            ^^PCI0.SBRG.EC0._Q12 ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x8A))
                        {
                            ^^PCI0.SBRG.EC0._Q72 ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0x38))
                        {
                            ^^PCI0.SBRG.EC0._Q6B ()
                            Return (Zero)
                        }

                        If ((IIA1 == 0xAE))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0x7C))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0x9E))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xA8))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xA9))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xAA))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xAB))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xB3))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xB2))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0xB3))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0x4B))
                        {
                            IANE (IIA1)
                            Return (Zero)
                        }

                        If ((IIA1 == 0x6A))
                        {
                            M460 ("jacky_6a function\n", Zero, Zero, Zero, Zero, Zero, Zero)
                            IANE (IIA1)
                            Return (Zero)
                        }

                        Return (One)
                    }

You can replicate each action manually by taking a code from lines like : If ((IIA1 == 0xAA)) And running following command in powershell as admin :

Invoke-CimMethod (Get-CimInstance -Namespace root/wmi -ClassName AsusAtkWmi_WMNB) -MethodName DEVS -Arguments @{Device_ID=0x00100021; Control_status=0xAA}

Where Control_status = 0xAA is the "hotkey action" that you want to send.

Try to find ones that are responsible for second screen / pgup stuff. I would suggest to go from the end as majority of actions in the beginning are same as on G14 (so they are just regular FN + F-row keys)

AnhPham1408 commented 1 year ago

0x4B is changing between arrows and pgup/pgdn. 0x6A is to turn on/off second display. In addition, here is the different between duo 16 keyboard and others sibling. image image F1-F4, F11

seerge commented 1 year ago

@AnhPham1408 oke, great. Can you check this build ? GHelper.zip

AnhPham1408 commented 1 year ago

Sadly it is still not working yet. As soon as I press the button, the log file show that it's spamming key 106 or 75 until I exit. log.txt log.txt

seerge commented 1 year ago

@AnhPham1408 then it looks like those codes are only emitting keypress (so app catches it in turn), but not a real "action" (i.e. display switch).

It makes task much more difficult to do. As then it should be some other way to turn display off for example.

I see couple of endpoints that could be screen (but may be something absolutely different)

                    If ((IIA0 == 0x00060023))
                    {
                        Local0 = (IIA1 >> 0x09)
                        If (((Local0 & One) == One))
                        {
                            VBOF = One
                            Local0 = (IIA1 >> 0x18)
                            Local0 *= 0x0100
                            VBOF |= Local0 /* \_SB_.VBOF */
                        }
                        Else
                        {
                            VBOF = Zero
                        }

                        Local0 = (IIA1 & 0xFF)
                        ^^PCI0.SBRG.EC0.STA9 (One, Local0)
                        Local0 = (IIA1 >> 0x08)
                        Local1 = ^^PCI0.SBRG.EC0.STA8 (Zero)
                        If (((Local0 & One) == One))
                        {
                            Local1 |= 0x02
                            Local2 = (Local1 & 0x0F)
                            ^^PCI0.SBRG.EC0.STA9 (Zero, Local1)
                        }
                        Else
                        {
                            Local1 &= 0xFD
                            Local2 = (Local1 & 0x0F)
                            ^^PCI0.SBRG.EC0.STA9 (Zero, Local1)
                        }

                        Return (One)
                    }

                    If ((IIA0 == 0x00060026))
                    {
                        Local0 = ^^PCI0.SBRG.EC0.STA8 (Zero)
                        If ((IIA1 == One))
                        {
                            Local0 |= 0x04
                            ^^PCI0.SBRG.EC0.STA9 (Zero, Local0)
                        }
                        Else
                        {
                            Local0 &= 0xFB
                            ^^PCI0.SBRG.EC0.STA9 (Zero, Local0)
                        }

                        Return (One)
                    }

Try 0x00060023 and 0x00060026 as device ids and 1 / 0 as ON / OFF switches in powershell

Invoke-CimMethod (Get-CimInstance -Namespace root/wmi -ClassName AsusAtkWmi_WMNB) -MethodName DEVS -Arguments @{Device_ID=0x00060026; Control_status=1}
AnhPham1408 commented 1 year ago

None of them are correct one. For turn on/off screen, is it possible to simulate the windows project between PC screen only and extend display ? Cause I find the behavior is the same. image

seerge commented 1 year ago

@AnhPham1408 Yes, on G14 it's a fn+F9 function (it literally opens that menu) Is that what you want?

AnhPham1408 commented 1 year ago

That's right, duo FN + F9 does that too. However, can it be running on background and auto apply between two modes (PC screen only and extended) when key 106 is pressed?

seerge commented 1 year ago

@AnhPham1408 i'm not sure, i quickly googled and it seems that WIN+P combo is the only one that exists , you can not specify anyhow what to do inside that menu

AnhPham1408 commented 1 year ago

No worries. Thanks for your reply. It seems like the function it more complicated than I thought.

seerge commented 1 year ago

@AnhPham1408 i have googled more, found that win+P actually calls command that is supposed to take parameter (i.e. what mode to set)

https://www.addictivetips.com/windows-tips/change-windows-10-projection-mode-with-keyboard-shortcut/

But it doesn't work on windows 11, just shows popup

So, in short - i'm not aware how to do that :)

I'm closing this as out of scope then, sorry