/*
fixMargins for TI-Nspire OS 3.6
Copyright (C) 2014 Levak
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#define asm __asm__ /* std=c99 */
#include
#define PROG_NAME "fixMargins"
static const char *error_title = "Error " PROG_NAME;
static const char *title = PROG_NAME;
static const char *successHook = "Hook successfully installed !";
static const char *alreadyInstalled = "Hook already installed !";
static const char *notAppliableHook = "Hook is not appliable to that TI-Nspire model nor OS version.";
static const int hook_getPos_addrs[] = {0x0, 0x0, // Clickpad / Touchpad 3.1
0x0, 0x0, // CX 3.1
0x0, 0x0, // CM 3.1
0x10004ecc, 0x10004e9c, // Clickpad / Touchpad 3.6
0x10004E64, 0x10004E64}; // CX 3.6
static const int hook_getPos_values[] = {0x0, 0x0,
0x0, 0x0,
0x0, 0x0,
0xE3520000, 0xE3520000,
0xE3520000, 0xE3520000};
static const int hook_callee_addrs[] = {0x0, 0x0,
0x0, 0x0,
0x0, 0x0,
0x10120274, 0x1012089c,
0x1011fcb8, 0x10120310};
#define HOOK_GETPOS_ADDR (nl_osvalue((int*)hook_getPos_addrs, sizeof(hook_getPos_addrs)/sizeof(hook_getPos_addrs[0])))
#define HOOK_GETPOS_VALUE (nl_osvalue((int*)hook_getPos_values, sizeof(hook_getPos_values)/sizeof(hook_getPos_values[0])))
#define HOOK_CALLEE_ADDR (nl_osvalue((int*)hook_callee_addrs, sizeof(hook_callee_addrs)/sizeof(hook_callee_addrs[0])))
static unsigned D2Editor_move_addrs[] = {0x0, 0x0,
0x0, 0x0,
0x0, 0x0,
0x10044ee4, 0x10044e44,
0x10044434, 0x100443C4};
#define D2Editor_move SYSCALL_CUSTOM(D2Editor_move_addrs, void, void * /* D2Editor */, int /* x */, int /* y */)
static unsigned int *callee = NULL;
HOOK_DEFINE(hook_getPos) {
unsigned int *r2 = (unsigned int*)(HOOK_SAVED_REGS(hook_getPos)[2] /* r2 */);
unsigned int *r3 = (unsigned int*)(HOOK_SAVED_REGS(hook_getPos)[3] /* r3 */);
unsigned int *lr = (unsigned int*)(HOOK_SAVED_REGS(hook_getPos)[13] /* lr */);
/* If we have a warning icon, offset by 0x12 the D2Editor. */
if (lr == callee)
{
void **histRow = (void **)(HOOK_SAVED_REGS(hook_getPos)[4] /* r4 */);
if (histRow != NULL)
{
void **d2editor = histRow[0x24 / 4];
if (d2editor != NULL)
D2Editor_move(d2editor, 0x12, (int)(d2editor[0x8 / 4]));
}
}
/* Always assign margin to 0 */
*r2 = 0x0;
*r3 = 0x10;
HOOK_RESTORE_RETURN(hook_getPos);
}
int main(int argc, char* argv[]) {
if(argc < 1) return 0;
argv = argv;
callee = (unsigned int*) HOOK_CALLEE_ADDR;
/* If hook is not appliable */
if (((int)HOOK_GETPOS_VALUE) == 0)
show_msgbox(error_title, notAppliableHook);
else
{
/* If hook isn't already installed */
if (*((int*)HOOK_GETPOS_ADDR) == HOOK_GETPOS_VALUE)
{
/* Remove everything */
unsigned int *p = (unsigned int *) HOOK_GETPOS_ADDR;
for (unsigned int i = 0; i < 8; ++i)
p[i] = 0;
/* Install hook */
HOOK_INSTALL(HOOK_GETPOS_ADDR, hook_getPos);
nl_set_resident();
if (!nl_isstartup())
show_msgbox(title, successHook);
}
else
show_msgbox(error_title, alreadyInstalled);
}
return 0;
}