Monday, November 14, 2011

Mouse controls in Firefox: Going from the ground up

So we were tasked with trying to find some way of manipulating the mouse controlling code for the Firefox browser. For those who haven't seen it before, the Firefox code base is massive, so randomly choosing where to start will likely leave you stranded with no way to find what your looking for. It is in your best interest to start from something you are already familiar with and move from there. Even in foreign code, there will be many overlapping tools or code bases you are likely to already be familiar with. So I started from the lowest level I could find, simply because I am most comfortable and knowledgeable there, which in this case was the Windows API.

So I went into this thinking two things:
  • I am trying to find where the browser gets the mouse data so I can manipulate it
  • This build is compiled on Windows, so it needs to talk to the Windows API to get hardware input
So this left me with an easy opening, I'd simply search through the code base looking for Windows API input based function calls, and that would narrow down my search to a few files. It did, leading me to the \widget\src\windows\ folder. From there I found nsWindow.h and nsWindow.cpp; after glancing through the .h file, I knew I was looking for things that modified the sLastMousePoint variable. With a quick flip through the CPP file, I found where it was initialized, and where it was updated, the DispatchMouseEvent function. Having had the needed information passed in by the function, I glanced down to find the GET_Y_LPARAM functions that set the event pointer position which later altered the sLastMousePoint variable. Knowing I had found the entry point for the mouse information, I simply swapped the X and Y values for the mouse and tested it. As expected, the browser now though the movement on the X was on the Y and vice versa. With that working, I called it a day, I now knew where the raw mouse information was injected from the OS.

If anyone wants more information on this, comment and I'll post an updated post with more explanation.

**Update** - If my previous explanation was too wordy, here is a simple code sample.

mozilla-central\widget\src\windows\nsWindows.cpp

bool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam,LPARAM lParam, bool aIsContextMenuKey,PRInt16 aButton, PRUint16 aInputSource)
{
bool result = false;
UserActivity();

...

nsIntPoint eventPoint;

eventPoint.x = GET_Y_LPARAM(lParam);
eventPoint.y = GET_X_LPARAM(lParam);

nsMouseEvent event(true, aEventType, this, nsMouseEvent::eReal,aIsContextMenuKey
? nsMouseEvent::eContextMenuKey : nsMouseEvent::eNormal);
...

No comments:

Post a Comment