Hier finden sich ein Paar Erkenntnisse, die sich aus der Beschäftigung mit dem vusb Treiber ergeben haben.

Im OBDev code wird der Modifier mit dieser Zeile deklariert:

static uchar    reportBuffer[2];    /* buffer for HID reports */

Da ein uchar (unsigned char) ein Byte groß ist, liegen uns hier 16 Bit an zusammenliegendem Speicher vor.

uint8_t count3 = 254;
[...]
if(count3>=254){ // sendet 2x die Null (einmal als termination) und rollt dann auf null über, da der counter ein unsigned 8bit int ist
    count3++;
    keyDidChange = 1;
    key = 0;
}
*(int *)reportBuffer = (key<<8)|0;

Das zugehörige Bitmuster sieht dann, beim Beispiel key=4 so aus:

0100 0000
*(int *)reportBuffer = (key<<8)|append;

wobei die lokale Variable append eben diesen SHIFT keypress enthält, der numerisch 2 ist (1«1), also 1*(2**1). Der Fkt-Prototyp muss entsprechend angepasst werden. Das Bitmuster:

0100 0010

Anschließend kommt man am Problem des „loslassen“ der Tasten an, auch wenn man meinen könnte bei einem „nicht modifizierten“ Tastendruck wie im Beispiel mit vier würde das Rechte byte bereits als „release“-Sequenz gelten, ist das keineswegs so. Offensichtlich wird das niederwertigste Bit LSB zuerst verarbeitet, denn Shift muss ja vor der Buchstaben-Taste gedrückt sein. Deshalb sendet man, am vorhergehenden Beispiel mit Modifier, auch zwei 0-Sequenzen hintereinander, Um zu signalisieren dass Beide Tasten losgelassen wurden. Ich (bongo) habe das so gelöst:

if(key != 0){    // lässt regulären Key los, falls gedrückt 
	keyDidChange = 1;
	key = 0;
}
else if(append){ // lässt modifier los, falls gedrückt, immer nach key
	keyDidChange = 1;
	key = 0;
	append=0;
}
else if(count3 < sizeof(geostr)){   //holt sich den nächsten char aus einem Array und sendet ihn ggf. mit append
	if(count3 < 6 || count3==8 || count3==16){
		append = MOD_SHIFT_LEFT; 
	}
	key = geostr[count3];
	count3++;
	keyDidChange = 1;
}
else {
	key = 0; // die Zeichenkette wurde zu-ende abgearbeitet, sende abschließendes Byte
	append = 0;
	keyDidChange = 1;
}