Using w and /dev solutions will only get you so far, since it could be that the user is around, but has not typed anything in the shell - for example, he/she could be playing some game. A better approach would be to poll /proc/interrupts. The local interrupts for the mouse and keyboard are often under "i8042" (though in some rare cases it might be different). You might want to try: "grep i8042 /proc/interrupts". This will yield IRQ 1 (keyboard) and IRQ 12 (usually, the mouse). You can get the values, store them, and then poll occasionally (no callback, alas), to get the counts. If the numbers changed, interrupts occurred - meaning keyboard (IRQ 1) or mouse (IRQ 12) were touched/pressed etc. Key presses generally generate two interrupts (key down, key up). Mouse movement is more erratic.
This has several advantages:
1) If the user so much as touches the mouse, or presses a key - you know
2) You can do so programmatically (i.e. fopen() /proc/interrupts , or (alternatively) /proc/stat, and get the "intr" line) and fread() the relevant lines
3) You don't even need to be root for this.