USB keyboard, difficulty passing decimal key arguments to a function

Based on the chart here-http://arduino.cc/en/Reference/KeyboardModifiers
I’m trying to pass the decimal values of modifier keys into a function then to Keyboard.press( )
Its not quite working though, Keyboard.press doesn’t take these arguments as suggested I suspect.
though it does for write, which is understandable but I’m trying to create a function that makes key bindings that requires .press.

Here what I have so far, dice on specialKey(), no dice on combo()

void specialKey(int presses, int key)
{
  for(int i=0;i<presses;i++){
    Keyboard.write(key);
  }
}

void combo(int key1,int key2)
{
  Keyboard.press(key1);
  Keyboard.press(key2);
  delay(5);
  Keyboard.releaseAll();
}

void combo(int key1,int key2, int key3)
{
  Keyboard.press(key1);
  Keyboard.press(key2);
  Keyboard.press(key3);
  delay(5);
  Keyboard.releaseAll();
}

Any ideas? I cant pass things like KEY_LEFT_CTRL I suppose the decimal value 128 is necessary.
I’m probably missing something really simple here.

The way I read the documentation, you need to use two Keyboard.write() calls to send the modifier key, then the to-be-modified key, NOT Keyboard.press().

I just tested the capability of keyboard.write( ) to be sure but it can not handle modifier combos

for example in order to change the keyboard layout on my computer (dvorak to qwerty) I have the combo set to left shift and left alt

if i do this

combo(129, 130);

void combo(int key1,int key2)
{
  Keyboard.write(key1);
  Keyboard.write(key2);
}

nothing happens because the keys are pressed an not held

if I did this in the main body of the code

  Keyboard.press(KEY_LEFT_SHIFT);
  Keyboard.press(KEY_LEFT_ALT);
  delay(5);
  Keyboard.releaseAll();

everything works the way I would expect.
however, there is allot of repetitive behavior that uses those four lines, so I guess the real question is, how to do I make those four lines a function and be able to pass in the modifiers as arguments?

I also tried this

void combo(int key1,int key2)
{
  Keyboard.press(key1, DEC);
  Keyboard.press(key2, DEC);
  delay(5);
  Keyboard.releaseAll();
}

keyboard.press() only takes one argument though unlike some of the serial functions, that would assure decimal entry with something like that.

I also tried this Code:

void combo(int key1,int key2) { Keyboard.press(key1, DEC); Keyboard.press(key2, DEC);

What do you think the , DEC part is doing?

What do you think the , DEC part is doing?

preventing the code from compiling.

Looking a the serial documentation again I suppose it would still not help towards my end, even if it worked the same way. So I guess that particular effort was based on a poor assumption.

So I guess that particular effort was based on a poor assumption.

It was. The assumption that arguments to one function will work the same way with another function seems to be quite common, though. Even if I don’t understand it.

if I did this in the main body of the code

everything works the way I would expect.

Then, why don’t you do the same thing in the function?

The assumption that arguments to one function will work the same way with another function seems to be quite common, though. Even if I don’t understand it.

I think folks like my self, not used to the world of programming are just way too used to implicit language vs explicit language. So they mistakenly apply implicit skills to an explicit problem like I did.

Then, why don’t you do the same thing in the function?

combo(KEY_LEFT_SHIFT,  KEY_LEFT_ALT);//<---not ints or chars
// but those are the arguments that I know to work

//it is suggested that these could be represented as 129 and 130
combo(129, 130);// does't function as expected ether

void combo(char key1, char key2)//<---I don't want to pass a string,
//--------------------------- and If that is the way to do it, I'm not sure how
{
  Keyboard.press(key1);
  Keyboard.press(key2);
  delay(100);
  Keyboard.releaseAll();
}

I just tried setting these as strings which would not be awful If I keep them in progmem but yet again I’m stumped on how to properly pass the data type to the function.

but yet again I'm stumped on how to properly pass the data type to the function.

Where/how are KEY_LEFT_SHIFT and KEY_LEFT_ALT defined?

What, exactly, does this combination modify? It looks to me like the shift key is modifying the Alt key, which doesn't make sense.

What, exactly, does this combination modify?

on my computer, pressing these two keys simultaneously would change the layout to qwerty which is necessary for forthcoming Keyboard.print() statements to not look like gibberish

regardless that fine detail, I've also tried things like alt f2 (run promt) to no result (keys which are all the same with my layout)

on my computer, pressing these two keys simultaneously would change the layout to qwerty which is necessary for forthcoming Keyboard.print() statements to not look like gibberish

OK. That's a new use to me.

Where/how are KEY_LEFT_SHIFT and  KEY_LEFT_ALT defined?

http://arduino.cc/en/Reference/KeyboardModifiers by the function, I haven't looked at its source yet so i'm not really sure

OK. That's a new use to me.

That detail in particular in only necessary for odd balls like my self using a non-standard key layout, but its really more of the context of the issue then the issue its self.

KEY_LEFT_SHIFT and KEY_LEFT_ALT (and others) are defined in USBAPI.h, using #define statements.

The Keyboard class is defined in HID.cpp, where press() is defined as taking a uint8_t. So, that is what your function should use.

The Keyboard class is defined in HID.cpp, where press() is defined as taking a uint8_t. So, that is what your function should use.

I’m really confused as to what is going on then, because looking at the source, I can see that Keyboard.write() uses press and press takes decimals… well… maybe not for modifiers, guess I wouldn’t have been able to test that with release right there.
for context

size_t Keyboard_::write(uint8_t c)
{	
	uint8_t p = press(c);		// Keydown
	uint8_t r = release(c);		// Keyup
	return (p);					// just return the result of press() since release() almost always returns 1
}

So there must be something in press that forces modifiers to be taken as their keywords, in which case i’m out of luck. I just don’t see it though… but I am little thick headed… might be right there in the _keyReport.modifiers exception I just don’t understand and I’m having a hard time finding where that object is.

size_t Keyboard_::press(uint8_t k) 
{
	uint8_t i;
	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		_keyReport.modifiers |= (1<<(k-128));//<-------------------right here?
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);
		if (!k) {
			setWriteError();
			return 0;
		}
		if (k & 0x80) {						// it's a capital letter or other character reached with shift
			_keyReport.modifiers |= 0x02;	// the left shift modifier
			k &= 0x7F;
		}
	}
	
	// Add k to the key report only if it's not already present
	// and if there is an empty slot.
	if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
		_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
		_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
		
		for (i=0; i<6; i++) {
			if (_keyReport.keys[i] == 0x00) {
				_keyReport.keys[i] = k;
				break;
			}
		}
		if (i == 6) {
			setWriteError();
			return 0;
		}	
	}
	sendReport(&_keyReport);
	return 1;
}

I'm really confused as to what is going on then, because looking at the source, I can see that Keyboard.write() uses press and press takes decimals

I got lost here. What do you mean by "and press takes decimals"? decimals is not a type. Or a meaningful description of a numeric value, either.

I got lost here. What do you mean by "and press takes decimals"? decimals is not a type. Or a meaningful description of a numeric value, either.

basically unsigned byte 1100001 goes through but unsigned byte 10000010 gets ignored and I am not really sure why because if the latter value didn't get ignored my program would work the way I expect it to.

basically unsigned byte 1100001 goes through but unsigned byte 10000010 gets ignored and I am not really sure why because if the latter value didn't get ignored my program would work the way I expect it to.

Goes through what? How do you know that it goes through whatever?

solution... embarrassingly enough the answer was pulled from my first sketch from a couple of weeks ago... real simple, assign the key definitions to chars. Why this works or why I did this to begin with and forgot, I couldn't tell you.

char super= KEY_LEFT_GUI;
char ctrl= KEY_LEFT_CTRL;
char alt= KEY_LEFT_ALT;
char f4= KEY_F4;
char f2= KEY_F2;
char tab= KEY_TAB;

void setup()
{
  Keyboard.begin();
  delay(500);
  combo(alt, f2);
  delay(200);
  Keyboard.println("mate-terminal");
  delay(200);
}

void loop()
{
}

void combo(char key1, char key2)
{
  Keyboard.press(key1);
  Keyboard.press(key2);
  delay(100);
  Keyboard.releaseAll();
}

passing char shift=129 must be blocked by magic smoke, because this is the only thing that I could get to work.

passing char shift=129 must be blocked by magic smoke, because this is the only thing that I could get to work.

Possibly because char is a signed type, with a valid range of values from -128 to 127.

Possibly because char is a signed type, with a valid range of values from -128 to 127.

good point, i'm kinda all over all over the place in how I misuse and understand terminology. However tested with the byte data type the same results occur