Use XGetPointerMapping/XSetPointerMapping to swap mouse buttons - linux

I have found these two APIs at http://linux.die.net/man/3/xgetpointermapping. I think that they can be used to swap mouse buttons on linux or mac system. I used it in following way:
Display * curdisp; // Current display.
char curmap[MAX_NUM];// Current mapping.
int nmap; // number of mappings.
curdisp = XOpenDisplay(NULL);
nmap = XGetPointerMapping(curdisp, curmap, MAX_NUM);
if(!nmap)
return -1;
if(curmap[0] == '1' && curmap[2] == '3') {
curmap[0] = '3';
curmap[2] = '1';
} else {
curmap[0] = '1';
curmap[2] = '3';
}
//Set the mapping.
nmap = XSetPointerMapping(curdisp, curmap, nmap);
But the call XSetPointerMapping returns 0 and there is no effect on mouse button.
Can anyone give some example of swapping mouse button using XSetPointerMapping? or How to use it correctly? Will it work immediately?
The OS being used is Mac OS X 10.7.4.

The button numbers are stored as unsigned char but are not stored as characters.
Change '1' and '3' to 1 and 3.
Your code maps them to buttons 49 and 51 and does affect the buttons making button 1 and 3 unusable.

Related

Is scan code the same on all keyboards

I got problem when one of my customer complains about they use azerty keyboard and they can't use my product. So I decide to use scan code instead of virtual key. I found the function MapVirtualKey is really useful for me to achieve that. But in some situation, I don't want to use MapVirtualKey function but use the number itself, like {if(isKeyDown[30])return 'A';} but I go around the internet and realize that some source tell that their keyboard scan code is not like mine, like in this image
I don't understand it, why it's different from my keyboard's scan code, and even different from this MS scan code table
So I really wonder, Is it safe to use
if (isDownNow[48])
return 'B';
instead of
if (isDownNow[MapVirtualKey('B', MAPVK_VK_TO_VSC)])
return 'B';
Thank you for reading :)
Edit:
I think I have a solution for the problem above, instead of call MapVirtualKey every time, I will store the map in an array. But new problem comes up.
I don't have a azerty keyboard so I can't test this, I only have a qwerty keyboard, so I got confuse on this problem:
I got this function to store my map.
void MapKeyData()
{
for (int i = 0; i < KEYS_SIZE; i++)//KEYS_SIZE=255
mapKey[i] = MapVirtualKey(i, MAPVK_VK_TO_VSC);//mapKey is unsigned char array
}
But I want the Z in normal keyboard (qwerty keyboard) map with the W in azerty keyboard. But as the function MapKeyData above, I think the Z in qwerty keyboard still map with the Z in azerty keyboard which is definitely not my purpose, I want to keep the keyboard layout, not the key itself. But as I said, I don't know if the scan code is the same on every keyboard as the first picture show that the keycode different from my scan code.
Thank for reading :)
Yes, scan code is the same on all keyboard layout. I've tested this fact by changing my keyboard layout to other layout with windows settings.
So to solve the different keyboard layout across PCs, I created an array of unsigned char that stores the scan code of keys: The index of the item is the key on my standard QWERTY keyboard, the value of the item is the scan code. This way, I can easily map the key on my QWERTY to its scan code so that I can work with the scan code.
mapKey['A'] = 30; //Key 'A' on QWERTY keyboard has scan code = 30
mapKey['B'] = 48;
mapKey['C'] = 46;
mapKey['D'] = 32;
mapKey['E'] = 18;
mapKey['F'] = 33;
mapKey['G'] = 34;
mapKey['H'] = 35;
mapKey['I'] = 23;
mapKey['J'] = 36;
mapKey['K'] = 37;
mapKey['L'] = 38;
mapKey['M'] = 50;
mapKey['N'] = 49;
mapKey['O'] = 24;
mapKey['P'] = 25;
mapKey['Q'] = 16;
mapKey['R'] = 19;
mapKey['S'] = 31;
mapKey['T'] = 20;
mapKey['U'] = 22;
mapKey['V'] = 47;
mapKey['W'] = 17;
mapKey['X'] = 45;
mapKey['Y'] = 21;
mapKey['Z'] = 44;
mapKey[VK_LEFT] = 75;
mapKey[VK_RIGHT] = 77;
mapKey[VK_RETURN] = 28;
... more if needed
See my answer here -- tl;dr: use WM_CHAR, not MapVirtualKey

Getting Barcode Scanner MT2000 to Move to Next Focus

I am trying to move to the next focus of an application by transmit a TAB or ENTER character to the host from my Motorola MT2070 Barcode Scanner.
I have tried using the SendLabel method as follows
string barcode = "Hello";
int count = 1;
SendBarcode(new LabelData(barcode + "\t" + count.ToString(), Options.BarcodeType));
count++;
}
private bool SendBarcode(LabelData label)
{
RESULTCODE result = RESULTCODE.E_OK;
try
{
result = Program.ScannerServicesClient.SendLabel(label, 10000);
}
catch
{
result = RESULTCODE.E_HOST_NOT_READY;
}
if (result != RESULTCODE.E_OK)
{
MsgBox.Error(listForm, Properties.Resources.StrErrorCouldntSendBarcode);
}
return result == RESULTCODE.E_OK;
}
Unfortunately the "\t" does not translate into an actual TAB keystroke in Keyboard mode.
When scanning in NOTEPAD the 5 spaces of the tab show up, but it doesn't work to move the focus to the next field as hitting TAB does in Excel or other applications.
What should I be transmitting in place of the \t?
Thanks!
I assume this won't work, because it is not a normal/manual input from your keyboard. It is a value passed from a barcode to the text-property of your field. So you have to handle this different.

How to add window padding in NCurses?

I have my window
WINDOW *win = newwin(40, 40, 3, 3);
When some text is entered and is spanning more lines, what is the best way to preserve the neat whitespace around the inner borders of the window? I cannot seem to find a way to give a window this kind of property in NCurses.
I guess a way to make padding is to create another window inside this one. There must be a cleaner way.
William McBrine is absolutely sure. The simplest way to retain a box around a window is to create the box in a window which surrounds it. That is because
changes to the inner box have no effect on the box
there is a function box which draws a box along the edges of a given window.
Several of the ncurses test-programs use this feature. For instance, one of the menu entries in the main test-program (in ncurses.c) responds to a w by creating a window to hold the box, then a window to hold its contents, and draws a box in the former before continuing to accept input in the new inner box:
} else if (c == 'w') {
int high = getmaxy(win) - 1 - first_y + 1;
int wide = getmaxx(win) - first_x;
int old_y, old_x;
int new_y = first_y + getbegy(win);
int new_x = first_x + getbegx(win);
getyx(win, old_y, old_x);
if (high > 2 && wide > 2) {
WINDOW *wb = newwin(high, wide, new_y, new_x);
WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1);
box(wb, 0, 0);
wrefresh(wb);
wmove(wi, 0, 0);
remember_boxes(level, wi, wb);
wgetch_test(level + 1, wi, delay);
delwin(wi);
delwin(wb);
wgetch_help(win, flags);
wmove(win, old_y, old_x);
touchwin(win);
wrefresh(win);
doupdate();
}

Smartgwt addMember changes top of parent

I have several nested layouts (VLayouts and HLayouts), which are included inside a tab pane. In one of these layouts (VLayout), there is severall elements which are added or removed dynamically depending on a window of selection. The first time the user makes a selection, the pane moves up several pixels (and you will not see the upper part of the pane). The rest of times, the pain remains in the wrong place.
In summary, the first adding affects to the top of the pane, and the rest of adding/removing doesn't affect to it.
This only happens on Chrome. However, Firefox and IE work ok.
My code of adding is:
int total = itemsPanel.getMembers().length - 1;
while (total >=0) {
itemsPanel.removeMember(itemsPanel.getMember(total));
total--;
}
Record[] records = selectorWindow.getSelectedRows();
if (records != null) {
for (Record record : records) {
String name = record.getAttribute("keyRecord");
HLayout item = items.get(name);
itemsPanel.addMember(row);
}
}
if (itemsPanel != null) {
int r = 80;
if (Utils.isReducedHeight()) {
r = 120;
}
int visibleHeight = getVisibleHeight() - StyleUtils.HEADER_HEIGHT - r;
itemsPanel.setHeight(Math.max(1, Math.min(itemsPanel.getMembers().length * Utils.getRowHeight(), visibleHeight)));
int h = Math.min(itemsPanel.getHeight() + 10, visibleHeight);
containerItemsPanel.setHeight(h);
}
I'm using gwt 2.5.1 and smartgwt 3.0. Any idea?
Thanks in advance

Win32 Text Drawing Puzzle

I've got a little text drawing puzzle under Win32. I'm trying to draw some instructions for users of my application at the top of the window.
Please refer to the following window (I've changed the background color on the text so you can see the boundaries)
(source: billy-oneal.com)
I'm currently using DrawTextEx to draw the text to my window, but the problem is that it does not fill the entire RECTangle that I give it. Not drawing that area is just fine, until the window resizes:
(source: billy-oneal.com)
When the text is re wrapped due to the window sizing, because DrawTextEx doesn't clear it's background, these artifacts are leftover.
I tried using FillRect to fill in the area behind the text drawing call, which does eliminate the visual artifacts, but then causes the text to flicker constantly, as it is completely erased and then completely redrawn to the display.
Any ideas on how one might get the area not containing text to be drawn with the background color?
EDIT: I'd like to avoid having to double buffer the form if at app possible.
EDIT2: I solved the problem by only redrawing the text when I detect that the wrapping changes during a resize.
Use double buffering?
Draw everything to a bitmap and draw the bitmap to the window. Flickering is commonly a double buffering issue.
There are many possible solutions and without seeing your code, it's hard to tell which method would be best so I'd suggest taking a look at this article on flicker free drawing
SetBkMode + SetBkColor ?
Well since nobody seems to know what to do about it, I implemented it this way:
std::vector<std::wstring> wrapString(HDC hDC, const std::wstring& text, const RECT& targetRect, HFONT font)
{
std::vector<std::wstring> result;
RECT targetRectangle;
CopyRect(&targetRectangle, &targetRect);
//Calculate the width of the bounding rectangle.
int maxWidth = targetRectangle.right - targetRectangle.left;
//Draw the lines one at a time
std::wstring currentLine;
for(std::wstring::const_iterator it = text.begin(); it != text.end(); currentLine.push_back(*it), it++)
{
if(*it == L'\r' || *it == L'\n')
{ //Hard return
while(it != text.end() && (*it == L'\r' || *it == L'\n')) it++;
result.push_back(currentLine);
currentLine.clear();
}
else
{ //Check for soft return
SIZE sizeStruct;
GetTextExtentPoint32(hDC, currentLine.c_str(), static_cast<int>(currentLine.length()), &sizeStruct);
if (sizeStruct.cx > maxWidth)
{
std::wstring::size_type lineLength = currentLine.find_last_of(L' ');
if (lineLength == currentLine.npos)
{ //Word is longer than a line.
for(;it != text.end() && !iswspace(*it);it++) currentLine.push_back(*it);
}
else
{ //Clip word to line.
//Backtrack our scan of the source text.
it -= currentLine.length() - lineLength - 1;
//Remove the clipped word
currentLine.erase(lineLength);
}
result.push_back(currentLine);
currentLine.clear();
}
}
}
//Last remaining text.
result.push_back(currentLine);
return result;
}
void DrawInstructionsWithFilledBackground(HDC hDC, const std::wstring& text, RECT& targetRectangle, HFONT font, COLORREF backgroundColor)
{
//Set up our background color.
int dcIdx = SaveDC(hDC);
HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor);
SelectObject(hDC, backgroundBrush);
SelectObject(hDC, font);
SetBkColor(hDC, backgroundColor);
std::vector<std::wstring> lines(wrapString(hDC, text, targetRectangle, font));
for(std::vector<std::wstring>::const_iterator it = lines.begin(); it!=lines.end(); it++)
{
RECT backgroundRect = targetRectangle;
DrawText(hDC, const_cast<LPWSTR>(it->c_str()), static_cast<int>(it->length()), &backgroundRect, DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE);
backgroundRect.left = backgroundRect.right;
backgroundRect.right = targetRectangle.right;
if (backgroundRect.right >= backgroundRect.left)
FillRect(hDC, &backgroundRect, backgroundBrush);
ExtTextOut(hDC, targetRectangle.left, targetRectangle.top, ETO_OPAQUE, NULL, it->c_str(), static_cast<UINT>(it->length()), NULL);
targetRectangle.top += backgroundRect.bottom - backgroundRect.top;
}
instructionsWrap = lines;
//Restore the DC to it's former glory.
RestoreDC(hDC, dcIdx);
DeleteObject(backgroundBrush);
}
Get/Calculate the rect used by the DrawText call and clip it with something like ExcludeClipRect before calling FillRect

Resources