summaryrefslogtreecommitdiff
authorzecke <zecke>2004-03-02 21:04:44 (UTC)
committer zecke <zecke>2004-03-02 21:04:44 (UTC)
commitdcf196abd97485cd9634d6ac135028a605c54fb5 (patch) (side-by-side diff)
treea424872b45f52418e4c84148c7ed4cfcc0b1a681
parent0a67659dce57ac1475841838369e924f2441e991 (diff)
downloadopie-dcf196abd97485cd9634d6ac135028a605c54fb5.zip
opie-dcf196abd97485cd9634d6ac135028a605c54fb5.tar.gz
opie-dcf196abd97485cd9634d6ac135028a605c54fb5.tar.bz2
Fix key handling bug 1268
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/comm/keypebble/krfbdecoder.cpp79
1 files changed, 34 insertions, 45 deletions
diff --git a/noncore/comm/keypebble/krfbdecoder.cpp b/noncore/comm/keypebble/krfbdecoder.cpp
index 2c9ad71..db95154 100644
--- a/noncore/comm/keypebble/krfbdecoder.cpp
+++ b/noncore/comm/keypebble/krfbdecoder.cpp
@@ -196,33 +196,33 @@ void KRFBDecoder::gotServerInit()
static QString statusMsg = tr( "Waiting for desktop name..." );
emit status( statusMsg );
currentState = AwaitingDesktopName;
connect( con, SIGNAL( gotEnoughData() ), SLOT( gotDesktopName() ) );
con->waitForData( info->nameLength );
}
void KRFBDecoder::gotDesktopName()
{
assert( info );
assert( currentState == AwaitingDesktopName );
qWarning( "Got desktop name" );
- disconnect( con, SIGNAL( gotEnoughData() ),
+ disconnect( con, SIGNAL( gotEnoughData() ),
this, SLOT( gotDesktopName() ) );
char *buf = new char[ info->nameLength + 1 ];
CHECK_PTR( buf );
con->read( buf, info->nameLength );
buf[ info->nameLength ] = '\0';
info->name = buf;
qWarning( "Desktop: %s", info->name.latin1() );
delete buf;
// Get the format we'll really use and tell the server
decidePixelFormat();
sendPixelFormat();
@@ -250,33 +250,33 @@ void KRFBDecoder::decidePixelFormat()
//
// We'll use the minimum of the remote and local depths, UNLESS an
// eight bit session has been specifically requested by the user.
int screenDepth = QPixmap::defaultDepth();
int bestDepth = ( screenDepth > info->depth ) ? info->depth : screenDepth;
int chosenDepth;
if ( con->options()->colors256 )
chosenDepth = 8;
else
chosenDepth = bestDepth;
qWarning( "Screen depth=%d, server depth=%d, best depth=%d, " \
"eight bit %d, chosenDepth=%d",
screenDepth,
info->depth,
- bestDepth,
+ bestDepth,
con->options()->colors256, chosenDepth );
format->depth = chosenDepth;
// If we're using the servers native depth
if ( chosenDepth == info->depth ) {
// Use the servers native format
format->bpp = info->bpp;
// format->bigEndian = info->bigEndian;
format->bigEndian = true;
format->trueColor = info->trueColor;
format->redMax = info->redMax;
format->greenMax = info->greenMax;
format->blueMax = info->blueMax;
format->redShift = info->redShift;
format->greenShift = info->greenShift;
@@ -360,96 +360,96 @@ void KRFBDecoder::sendUpdateRequest( bool incremental )
con->write( &y, 2 );
con->write( &w, 2 );
con->write( &h, 2 );
// Now wait for the update
currentState = AwaitingUpdate;
connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
con->waitForData( UpdateHeaderLength );
}
void KRFBDecoder::gotUpdateHeader()
{
assert( currentState == AwaitingUpdate );
// qWarning( "Got update header" );
- disconnect( con, SIGNAL( gotEnoughData() ),
+ disconnect( con, SIGNAL( gotEnoughData() ),
this, SLOT( gotUpdateHeader() ) );
CARD8 msgType;
con->read( &msgType, 1 );
if ( msgType != UpdateId ) {
// We might have a bell or server cut
if ( msgType == ServerCutId ) {
oldState = currentState;
gotServerCut();
}
else if ( msgType == BellId ) {
oldState = currentState;
gotBell();
}
else {
int msg = msgType;
QString protocolError = tr( "Protocol Error: Message Id %1 was "
"found when expecting an update "
"message." ).arg( msg );
currentState = Error;
emit error( protocolError );
}
- return;
+ return;
}
CARD8 padding;
con->read( &padding, 1 );
con->read( &noRects, 2 );
noRects = Swap16IfLE( noRects );
// qWarning( "Expecting %d rects", noRects );
// Now wait for the data
currentState = AwaitingRectHeader;
connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
con->waitForData( RectHeaderLength );
}
void KRFBDecoder::gotRectHeader()
{
assert( currentState == AwaitingRectHeader );
// qWarning( "Got rect header" );
- disconnect( con, SIGNAL( gotEnoughData() ),
+ disconnect( con, SIGNAL( gotEnoughData() ),
this, SLOT( gotRectHeader() ) );
con->read( &x, 2 );
x = Swap16IfLE( x );
con->read( &y, 2 );
y = Swap16IfLE( y );
con->read( &w, 2 );
w = Swap16IfLE( w );
con->read( &h, 2 );
h = Swap16IfLE( h );
con->read( &encoding, 4 );
// CARD32 encodingLocal = Swap32IfLE( encoding );
- // qWarning( "Rect: x=%d, y= %d, w=%d, h=%d, encoding=%ld",
+ // qWarning( "Rect: x=%d, y= %d, w=%d, h=%d, encoding=%ld",
// x, y, w, h, encodingLocal );
//
// Each encoding needs to be handled differently. Some require
// waiting for more data, but others like a copyrect do not.
// Our constants have already been byte swapped, so we use
// the remote value as is.
//
if ( encoding == RawEncoding ) {
// qWarning( "Raw encoding" );
handleRawRect();
}
else if ( encoding == CopyRectEncoding ) {
// qWarning( "CopyRect encoding" );
handleCopyRect();
}
@@ -507,41 +507,41 @@ void KRFBDecoder::getRawRectChunk( int lines )
{
this->lines = lines;
CARD32 count = lines * w * format->bpp / 8;
// Wait for server init
// qWarning( "Waiting for raw rect chunk, %ld", count );
currentState = AwaitingRawRectChunk;
connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRawRectChunk() ) );
con->waitForData( count );
}
void KRFBDecoder::gotRawRectChunk()
{
assert( currentState == AwaitingRawRectChunk );
- disconnect( con, SIGNAL( gotEnoughData() ),
+ disconnect( con, SIGNAL( gotEnoughData() ),
this, SLOT( gotRawRectChunk() ) );
// qWarning( "Got raw rect chunk" );
//
// Read the rect data and copy it to the buffer.
//
-
+
// TODO: Replace this!
int count = lines * w * format->bpp / 8;
char *hack = new char[ count ];
con->read( hack, count );
buf->drawRawRectChunk( hack, x, y, w, lines );
delete hack;
// /TODO:
h = h - lines;
y = y + lines;
if ( h > 0 ) {
handleRawRect();
}
else {
noRects--;
@@ -707,33 +707,33 @@ void KRFBDecoder::gotServerCutText()
//
// Warning: There is a bug in the RFB protocol because there is no way to find
// out the codepage in use on the remote machine. This could be fixed by requiring
// the remote server to use utf8 etc. but for now we have to assume they're the
// same. I've reported this problem to the ORL guys, but they apparantly have no
// immediate plans to fix the issue. :-( (rich)
//
char *cutbuf = new char[ serverCutTextLen + 1 ];
CHECK_PTR( cutbuf );
con->read( cutbuf, serverCutTextLen );
cutbuf[ serverCutTextLen ] = '\0';
/* For some reason QApplication::clipboard()->setText() segfaults when called
- * from within keypebble's mass of signals and slots
+ * from within keypebble's mass of signals and slots
qWarning( "Server cut: %s", cutbuf );
QString cutText( cutbuf ); // DANGER!!
qApp->clipboard()->setText( cutText );
*/
delete cutbuf;
// Now wait for the update (again)
if ( oldState == AwaitingUpdate ) {
currentState = AwaitingUpdate;
connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
con->waitForData( UpdateHeaderLength );
}
else if ( oldState == Idle ) {
currentState = Idle;
}
@@ -785,57 +785,46 @@ void KRFBDecoder::sendKeyReleaseEvent( QKeyEvent *event )
int key;
key = toKeySym( event );
if ( key ) {
key = Swap32IfLE( key );
CARD8 mask = false;
CARD16 padding = 0;
con->write( &KeyEventId, 1 );
con->write( &mask, 1 );
con->write( &padding, 2 );
con->write( &key, 4 );
}
}
+
+
+//
+// The RFB protocol spec says 'For most ordinary keys, the 'keysym'
+// is the same as the corresponding ASCII value.', but doesn't
+// elaborate what the most ordinary keys are. The spec also lists
+// a set (possibly subset, it's unspecified) of mappings for
+// "other common keys" (backspace, tab, return, escape, etc).
+//
int KRFBDecoder::toKeySym( QKeyEvent *k )
{
- int ke = 0;
-
- ke = k->ascii();
- // Markus: Crappy hack. I dont know why lower case letters are
- // not defined in qkeydefs.h. The key() for e.g. 'l' == 'L'.
- // This sucks. :-(
-
- if ( (ke == 'a') || (ke == 'b') || (ke == 'c') || (ke == 'd')
- || (ke == 'e') || (ke == 'f') || (ke == 'g') || (ke == 'h')
- || (ke == 'i') || (ke == 'j') || (ke == 'k') || (ke == 'l')
- || (ke == 'm') || (ke == 'n') || (ke == 'o') || (ke == 'p')
- || (ke == 'q') || (ke == 'r') || (ke == 's') || (ke == 't')
- || (ke == 'u') || (ke == 'v') ||( ke == 'w') || (ke == 'x')
- || (ke == 'y') || (ke == 'z') ) {
- ke = k->key();
- ke = ke + 0x20;
- return ke;
- }
- // qkeydefs = xkeydefs! :-)
- if ( ( k->key() >= 0x0a0 ) && k->key() <= 0x0ff )
- return k->key();
-
- if ( ( k->key() >= 0x20 ) && ( k->key() <= 0x7e ) )
- return k->key();
-
- // qkeydefs != xkeydefs! :-(
- // This is gonna suck :-(
-
- int i = 0;
- while ( keyMap[i].keycode ) {
- if ( k->key() == keyMap[i].keycode )
- return keyMap[i].keysym;
- i++;
- }
+ //
+ // Try and map these "other common keys" first.
+ //
+ if ((k->key() >= Qt::Key_Escape) && (k->key() <= Qt::Key_F12)) {
+ for(int i = 0; keyMap[i].keycode != 0; i++) {
+ if (k->key() == keyMap[i].keycode) {
+ return keyMap[i].keysym;
+ }
+ }
+ }
- return 0;
+ //
+ // If these keys aren't matched, return the ascii code and let the
+ // server figure it out. We don't return k->key(), as the data in
+ // key differs between input methods, and we don't want special cases.
+ //
+ return k->ascii();
}
-