Thinking about this question a bit more, later it occurred to me that I already encapsulate everything. I've been doing it for so long, i don't even think about it.
For example, my basic mouse input routine in my in-house gamedev library is getmouse(&x,&y,&b) i've been using it since before mice had three buttons. it was originally driven off of dos interrupt 31H as i recall. it now runs the windows message pump and tracks mouse state changes, reporting back the current potiion and the pressed state of buttons 1 and 2. so getmouse() and the newer getmouse2(&x,&y,&b1,&b2,&b3) and mousewheel() routines encapsultate the mouse input of the underlying OS. same idea for keypressed(VK_CODE). its a wrapper that encapsulates the functionality of GetAsyncKeyState(). back in the DOS days, it took an unsigned char instead of a VK_CODE, and hooked the keybaord hardware interrupt to do its own hardware interrupt driven keyboard input..There also used to be an analog joystick API as well.
so input is encapsulated via:
getmouse()
getmouse2()
mousewheel()
keypressed()
i don't really require joystick or game controller input for anything i'm working on at the moment.
the next input layer up from keypressed,getmouse, getmouse2, and mousewheel is control_pressed(IN_FORWARD), which is part of the input mapper API. it has a bunch of predefined inputs like IN_FORWARD IN_ATTACK, IN_BLOCK, IN_USE, IN_JUMP, etc. these are mapped to keys or mouse buttons. when you call control_pressed(IN_WHATEVER), it in turn calls keypressed, getmouse, getmouse2, or mousewheeel, depending on what input that "move" is mapped to.
the basic GUI components - getstring, [popup] menu, and [multi-iine] message - just call keypressed or getmouse.
the first thing i do when i start using a new library is write a wrapper api that encapsulates just the functionality i need. as small and as simple as possible. so my keybpoard APi is just keypressed(), and my mouse API is covered with just getmouise2 and mousewheeel.
as an example, here's my wrapper API for xaudio2. i'm quite pleased, it came out nice and simple. but then again audio API's usually do.
void Zunpause_voice(int i); // i is voice #
void Zpause_voice(int i); // i is voice #
void Zshutdown_audio();
int Zloopwav(int i); // returns: Zvoice # on success. -1=create source voice error. -2=submit source buffer error. -3=start voice error.
int Zvoice_is_playing(int i); // returns: 0=no. 1=yes.
void Zstop_voice(int i); // i is voice #
int Zplaywav(int i); // returns: Zvoice # on success. -1=create source voice error. -2=submit source buffer error. -3=start voice error.
int Zloadwav(int i,char *s); // loads wav into slot i. s is filename. returns: 0=success. 1=open wav error. 2=read wav error.
int Zinit_audio(); // returns: 0=success. 1=Xaudio2 create error. 2=create master voice error.
void Zloadwavs(char *s2); // loads all wavs listed in the file wavs.dat in the current folder.
void Zdestroy_finished_voices();