void mouseScrollBy(double x, double y, bool continuous) { RECT rect; ::GetWindowRect(webViewWindow, &rect); // This value is taken from Source/WebCore/platform/win/WheelEventWin.cpp const float cScrollbarPixelsPerLine = 100.0f / 3.0f; if (x) { UINT scrollChars = 1; ::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0); x *= WHEEL_DELTA / scrollChars; if (continuous) x /= cScrollbarPixelsPerLine; MSG msg = makeMsg(webViewWindow, WM_MOUSEHWHEEL, MAKEWPARAM(0, x), MAKELPARAM(rect.left + lastMousePosition.x, rect.top + lastMousePosition.y)); dispatchMessage(&msg); } if (y) { UINT scrollLines = 3; ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0); y *= WHEEL_DELTA / scrollLines; if (continuous) y /= cScrollbarPixelsPerLine; MSG msg = makeMsg(webViewWindow, WM_MOUSEWHEEL, MAKEWPARAM(0, y), MAKELPARAM(rect.left + lastMousePosition.x, rect.top + lastMousePosition.y)); dispatchMessage(&msg); } }
static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); down = true; MSG msg = makeMsg(webViewWindow, WM_RBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); dispatchMessage(&msg); down = false; msg = makeMsg(webViewWindow, WM_RBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); dispatchMessage(&msg); return JSValueMakeUndefined(context); }
//================================================================== Exception::Exception( const DStr &msg, const Token *pTok/*=NULL */ ) { if ( pTok ) { makeMsg( mMsg, pTok->pSourceFileName, pTok->sourceLine, msg.c_str() ); } else mMsg = msg; }
//================================================================== Exception::Exception( const DStr &msg, const TokNode *pTokNode ) { if ( pTokNode && pTokNode->mpToken ) { const Token *pTok = pTokNode->mpToken; makeMsg( mMsg, pTok->pSourceFileName, pTok->sourceLine, msg.c_str() ); } else mMsg = msg; }
msg* readSALMsg(fdBundle* fdB){ fd_set set; struct timeval tv; int bytes = 0; char buff[BUFFSZ]; msg* retval = makeMsg(BUFFSZ); int errcode; int fd = fdB->fd; if(retval == NULL){ fprintf(stderr, "makeMsg in %d failed\n", getpid()); goto fail; } while(1){ restart: tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&set); FD_SET(fd, &set); errcode = select(fd + 1, &set, NULL, NULL, &tv); if(errcode == -1){ if(errno == EINTR){ continue; } perror("select error:"); goto fail; } if(FD_ISSET(fd, &set)){ if((bytes = read(fd, buff, BUFFSZ)) < 0){ if(errno == EINTR){ goto restart; } else { fprintf(stderr, "read in readSALMsg failed\n"); goto fail; } } if(bytes > 0){ if(addToMsg(retval, bytes, buff) != 0){ goto fail; } } else { /* no bytes there */ if(*(fdB->exit)){ break; } else { continue; } } } else { /* nothing to read of fd */ if(*(fdB->exit)){ break; } else { continue; } } } return retval; fail: return NULL; }
//================================================================== Exception::Exception( const FatBase &fatBase, const Fat8 &ch, const char *pFmt, ... ) { va_list vl; va_start( vl, pFmt ); char buff[2048]; vsnprintf_s( buff, sizeof(buff), _countof(buff)-1, pFmt, vl ); va_end( vl ); makeMsg( mMsg, fatBase.mFileNames[ ch.FNameIdx ].c_str(), ch.SrcPos, buff ); }
static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { MSG msg = makeMsg(webViewWindow, WM_LBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if (dragMode && !replayingSavedEvents) { msgQueue[endOfQueue++] = msg; replaySavedEvents(); } else doMouseUp(msg); return JSValueMakeUndefined(context); }
/// Send the array element ap[i] a whole set of marshalled messages. static void callMarshallElt(const CProxy_marshallElt &ap,int i) { // 1 ap[i].basic((unsigned char)basicData[0],(char)basicData[1], (short)basicData[2],(unsigned short)basicData[3], (int)basicData[4],(unsigned int)basicData[5], (long)basicData[6],(unsigned long)basicData[7], (float)basicData[8],(double)basicData[9]); flatStruct f; f.init(); ap[i].flatRef(f); // 2 pupStruct p; p.init(); ap[i].pupped(p); // 3 pupStruct p2; p2.init(new child); ap[i].puppedSubclass(p2); // 4 parent *sub=new child; ap[i].PUPableReference(*sub); // 5 ap[i].PUPablePointer(sub); // 6 delete sub; int n=0+13*i*i; int *arr=makeArr(1,n,0); ap[i].simpleArray(n,arr); // 7 delete[] arr; int m=1+i; int *arr2=makeArr(2,n*m,0); ap[i].fancyArray(arr2,n,m); // 8 delete[] arr2; int n1=2+7*i*i,n2=4+i; int *a1=makeArr(3,n1,1); int *a2=makeArr(4,n2+n,1); a1[0]=n2+1; a2[0]=n1+1; ap[i].crazyArray(a1,a2,n); // 9 delete[] a1; delete[] a2; int j; msgQ_t q; ap[i].msgQ(0,q); // 10 const int nQ=2; for (j=0;j<nQ;j++) q.enq(makeMsg(5,13+2*j)); ap[i].msgQ(nQ,q); // 11 for (j=0;j<nQ;j++) delete q.deq(); }
static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); down = true; int mouseType = WM_LBUTTONDOWN; if (argumentCount >= 1) { int mouseNumber = JSValueToNumber(context, arguments[0], exception); switch (mouseNumber) { case 0: mouseType = WM_LBUTTONDOWN; break; case 1: mouseType = WM_MBUTTONDOWN; break; case 2: mouseType = WM_RBUTTONDOWN; break; case 3: // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_BUTTONDOWN mouseType = WM_MBUTTONDOWN; break; default: mouseType = WM_LBUTTONDOWN; break; } } WPARAM wparam = 0; if (argumentCount >= 2) wparam |= buildModifierFlags(context, arguments[1]); MSG msg = makeMsg(webViewWindow, mouseType, wparam, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if (!msgQueue[endOfQueue].delay) dispatchMessage(&msg); else { // replaySavedEvents has the required logic to make leapForward delays work msgQueue[endOfQueue++].msg = msg; replaySavedEvents(); } return JSValueMakeUndefined(context); }
static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); down = true; MSG msg = makeMsg(webViewWindow, WM_LBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if (!msgQueue[endOfQueue].delay) dispatchMessage(&msg); else { // replaySavedEvents has the required logic to make leapForward delays work msgQueue[endOfQueue++].msg = msg; replaySavedEvents(); } return JSValueMakeUndefined(context); }
static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount < 2) return JSValueMakeUndefined(context); lastMousePosition.x = (int)JSValueToNumber(context, arguments[0], exception); ASSERT(!exception || !*exception); lastMousePosition.y = (int)JSValueToNumber(context, arguments[1], exception); ASSERT(!exception || !*exception); MSG msg = makeMsg(webViewWindow, WM_MOUSEMOVE, down ? MK_LBUTTON : 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if (dragMode && down && !replayingSavedEvents) { msgQueue[endOfQueue++].msg = msg; return JSValueMakeUndefined(context); } doMouseMove(msg); return JSValueMakeUndefined(context); }
//================================================================== Exception::Exception( const TokNode *pTokNode, const char *pFmt, ... ) { va_list vl; va_start( vl, pFmt ); char buff[4096]; vsnprintf_s( buff, sizeof(buff), _countof(buff)-1, pFmt, vl ); va_end( vl ); if ( pTokNode && pTokNode->mpToken ) { const Token *pTok = pTokNode->mpToken; makeMsg( mMsg, pTok->pSourceFileName, pTok->sourceLine, buff ); } else { mMsg = buff; } }
int send_cmd (int speed, int angle){ //Note: +ve angle is counter-clockwise // speed must be +- sign plus 2 digits // angle must be 3 digits in total // last char must be 'n' //msg format sent to serial: +ssaaan (s: speed, a: angle) char cspeed [5]; char cangle [5]; char msg[12]; char *p = &msg[0]; int pos; if (speed < 0) cspeed[0] = '-'; else msg[0] = '+'; pos=1; ///Speed if (speed == 0) sprintf(cspeed, "+00"); else if (speed < 0) sprintf(cspeed, "-10"); else if (speed == 10) sprintf(cspeed, "+10"); else if (speed == 1) sprintf(cspeed, "+01"); ///Angle sprintf(cangle,"%03d", angle); ///Speed & Angle sprintf(msg, "%s%sn", cspeed, cangle); //Original message (ex: +10275n) printf ("move_car: %s\n", msg); makeMsg (&msg, strlen(msg)); return write_pln_cmd (msg, 1); //'+10245n' } //move_car()
static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { int mouseType = WM_LBUTTONUP; if (argumentCount >= 1) { int mouseNumber = JSValueToNumber(context, arguments[0], exception); switch (mouseNumber) { case 0: mouseType = WM_LBUTTONUP; break; case 1: mouseType = WM_MBUTTONUP; break; case 2: mouseType = WM_RBUTTONUP; break; case 3: // fast/events/mouse-click-events expects the 4th button has event.button = 1, so send an WM_MBUTTONUP mouseType = WM_MBUTTONUP; break; default: mouseType = WM_LBUTTONUP; break; } } WPARAM wparam = 0; if (argumentCount >= 2) wparam |= buildModifierFlags(context, arguments[1]); MSG msg = makeMsg(webViewWindow, mouseType, wparam, MAKELPARAM(lastMousePosition.x, lastMousePosition.y)); if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) { msgQueue[endOfQueue++].msg = msg; replaySavedEvents(); } else doMouseUp(msg); return JSValueMakeUndefined(context); }
static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount < 1) return JSValueMakeUndefined(context); static const JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length"); COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); JSStringRef character = JSValueToStringCopy(context, arguments[0], exception); ASSERT(!*exception); int virtualKeyCode; int charCode = 0; int keyData = 1; bool needsShiftKeyModifier = false; if (JSStringIsEqualToUTF8CString(character, "leftArrow")) { virtualKeyCode = VK_LEFT; keyData += KF_EXTENDED << 16; // In this case, extended means "not keypad". } else if (JSStringIsEqualToUTF8CString(character, "rightArrow")) { virtualKeyCode = VK_RIGHT; keyData += KF_EXTENDED << 16; } else if (JSStringIsEqualToUTF8CString(character, "upArrow")) { virtualKeyCode = VK_UP; keyData += KF_EXTENDED << 16; } else if (JSStringIsEqualToUTF8CString(character, "downArrow")) { virtualKeyCode = VK_DOWN; keyData += KF_EXTENDED << 16; } else if (JSStringIsEqualToUTF8CString(character, "pageUp")) virtualKeyCode = VK_PRIOR; else if (JSStringIsEqualToUTF8CString(character, "pageDown")) virtualKeyCode = VK_NEXT; else if (JSStringIsEqualToUTF8CString(character, "home")) virtualKeyCode = VK_HOME; else if (JSStringIsEqualToUTF8CString(character, "end")) virtualKeyCode = VK_END; else if (JSStringIsEqualToUTF8CString(character, "insert")) virtualKeyCode = VK_INSERT; else if (JSStringIsEqualToUTF8CString(character, "delete")) virtualKeyCode = VK_DELETE; else if (JSStringIsEqualToUTF8CString(character, "printScreen")) virtualKeyCode = VK_SNAPSHOT; else if (JSStringIsEqualToUTF8CString(character, "menu")) virtualKeyCode = VK_APPS; else if (JSStringIsEqualToUTF8CString(character, "leftControl")) { virtualKeyCode = VK_CONTROL; keyData += makeKeyDataForScanCode(VK_LCONTROL); } else if (JSStringIsEqualToUTF8CString(character, "leftShift")) { virtualKeyCode = VK_SHIFT; keyData += makeKeyDataForScanCode(VK_LSHIFT); } else if (JSStringIsEqualToUTF8CString(character, "leftAlt")) { virtualKeyCode = VK_MENU; keyData += makeKeyDataForScanCode(VK_LMENU); } else if (JSStringIsEqualToUTF8CString(character, "rightControl")) { virtualKeyCode = VK_CONTROL; keyData += makeKeyDataForScanCode(VK_RCONTROL); } else if (JSStringIsEqualToUTF8CString(character, "rightShift")) { virtualKeyCode = VK_SHIFT; keyData += makeKeyDataForScanCode(VK_RSHIFT); } else if (JSStringIsEqualToUTF8CString(character, "rightAlt")) { virtualKeyCode = VK_MENU; keyData += makeKeyDataForScanCode(VK_RMENU); } else { charCode = JSStringGetCharactersPtr(character)[0]; virtualKeyCode = LOBYTE(VkKeyScan(charCode)); if (WTF::isASCIIUpper(charCode)) needsShiftKeyModifier = true; } JSStringRelease(character); BYTE keyState[256]; if (argumentCount > 1 || needsShiftKeyModifier) { ::GetKeyboardState(keyState); BYTE newKeyState[256]; memcpy(newKeyState, keyState, sizeof(keyState)); if (needsShiftKeyModifier) newKeyState[VK_SHIFT] = 0x80; if (argumentCount > 1) { JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], 0); if (modifiersArray) { int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); for (int i = 0; i < modifiersCount; ++i) { JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0); JSStringRef string = JSValueToStringCopy(context, value, 0); if (JSStringIsEqualToUTF8CString(string, "ctrlKey") || JSStringIsEqualToUTF8CString(string, "addSelectionKey")) newKeyState[VK_CONTROL] = 0x80; else if (JSStringIsEqualToUTF8CString(string, "shiftKey") || JSStringIsEqualToUTF8CString(string, "rangeSelectionKey")) newKeyState[VK_SHIFT] = 0x80; else if (JSStringIsEqualToUTF8CString(string, "altKey")) newKeyState[VK_MENU] = 0x80; JSStringRelease(string); } } } ::SetKeyboardState(newKeyState); } MSG msg = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYDOWN : WM_KEYDOWN, virtualKeyCode, keyData); if (virtualKeyCode != 255) dispatchMessage(&msg); else { // For characters that do not exist in the active keyboard layout, // ::Translate will not work, so we post an WM_CHAR event ourselves. ::PostMessage(webViewWindow, WM_CHAR, charCode, 0); } // Tests expect that all messages are processed by the time keyDown() returns. if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE) || ::PeekMessage(&msg, webViewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) ::DispatchMessage(&msg); MSG msgUp = makeMsg(webViewWindow, (::GetKeyState(VK_MENU) & 0x8000) ? WM_SYSKEYUP : WM_KEYUP, virtualKeyCode, keyData); ::DispatchMessage(&msgUp); if (argumentCount > 1 || needsShiftKeyModifier) ::SetKeyboardState(keyState); return JSValueMakeUndefined(context); }
msg* wrapper_readSalMsg(int fd){ char prompt[] = "sal > "; char *promptPointer = NULL; int bytes = 0, iteration = 0; msg* retval = makeMsg(BUFFSZ); if(retval == NULL){ fprintf(stderr, "makeMsg in %d failed\n", getpid()); goto fail; } while(1){ char buff[BUFFSZ]; announce("wrapper_readSalMsg\t:\tcommencing a read\n"); restart: if((bytes = read(fd, buff, BUFFSZ)) < 0){ announce("wrapper_readSalMsg\t:\tread error read returned %d bytes\n", bytes); if(errno == EINTR){ announce("readMsg in %d restarting after being interrupted by a signal\n", getpid()); goto restart; } if(errno == EBADF){ fprintf(stderr, "readMsg in %d failing because of a bad file descriptor\n", getpid()); goto fail; } fprintf(stderr, "Read in %d returned with nothing\n", getpid()); return retval; } announce("wrapper_readSalMsg\t:\tread read %d bytes\n", bytes); announce("Read the following: buff \t = \t %s",buff); if(addToMsg(retval, bytes, buff) != 0){ fprintf(stderr, "addToMsg (wrapper_readSalMsg) in %d failed\n", getpid()); goto fail; } iteration++; if((promptPointer = strstr(retval->data, prompt)) != NULL){ fd_set readset; struct timeval delay; int sret; announce("wrapper_readSalMsg\t:\tsaw the prompt, making sure!\n"); FD_ZERO(&readset); FD_SET(fd, &readset); delay.tv_sec = 0; delay.tv_usec = 0; sret = select(fd + 1, &readset, NULL, NULL, &delay); if(sret < 0){ fprintf(stderr, "wrapper_readSalMsg\t:\tselect error\n"); goto fail; } else if(sret == 0){ announce("wrapper_readSalMsg\t:\tdefinitely the prompt!\n"); break; } else { announce("wrapper_readSalMsg\t:\tsret = %d more coming! TOO CONFUSING\n", sret); goto fail; } } }/* while */ if(retval != NULL){ announce("wrapper_readSalMsg\t:\tretval->bytesUsed = %d\n", retval->bytesUsed); announce("wrapper_readSalMsg\t:\tretval->data = \n\"%s\"\n", retval->data); announce("==================================================\n"); promptPointer[0] = '\0'; /* chomp the prompt I */ retval->bytesUsed -= strlen(prompt) ; /* chomp the prompt II */ announce("wrapper_readSalMsg\t:\tretval->bytesUsed = %d\n", retval->bytesUsed); announce("wrapper_readSalMsg\t:\tretval->data = \n\"%s\"\n", retval->data); announce("==================================================\n"); if((retval->bytesUsed == 0) || ((retval->bytesUsed == 1) && (retval->data[0] == '\n'))){ sprintf(retval->data, "OK\n"); retval->bytesUsed = strlen("OK\n"); } } announce("\nwrapper_readSalMsg\t:\tfinishing a read\n"); return retval; fail: freeMsg(retval); retval = NULL; return retval; }
int main(int argc, char** argv){ int listenfd,connfd,n; int count =0; pid_t childpid; socklen_t clilen; char buf[MAXLINE]; struct sockaddr_in cliaddr,servaddr; struct sendLine* recvline; if((listenfd = socket(AF_INET,SOCK_STREAM,0))<0){ perror("failed to create socket"); exit(errno); } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERVER_PORT); bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); listen(listenfd,LISTENQ); printf("%s\n","server is running...waiting for connecting!"); for(;;){ count++; clilen = sizeof(cliaddr); connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen); printf("%s\n", "received request...."); if((childpid = fork())==0){ printf("child created to process the client request\n"); close(listenfd); struct WeathMsg weathmsg; struct recvLine sendline; char dayNum; char sign[3]; sign[2]='\0'; while((n=recv(connfd,buf,MAXLINE,0))>0){ recvline = (struct sendLine*)buf; bzero(&weathmsg,sizeof(weathmsg)); memset(sign,0x00,2); dayNum = 0x00; /*processing*/ if(recvline->lineHead[0]==0x01){ //comes the city name if(findCity(recvline->city)==1){ //have msg about the msg sign[0]=0x03; sign[1]=0x00; sendline = makeMsg(weathmsg,recvline->city,0x00,sign,0); send(connfd,(char*)&sendline,sizeof(sendline),0); } else{ // don't have msg about the city sign[0]=0x04; sign[1]=0x00; sendline = makeMsg(weathmsg,recvline->city,0x00,sign,0); send(connfd,(char*)&sendline,sizeof(sendline),0); } } else{ int sendNum; // one day or three day if(recvline->lineHead[1]==0x01){ // one day's weather msg sign[1]=0x41; sendNum=0; if(recvline->lineTail < 0x06){ sign[0]=0x01; } else{ sign[0]=0x02; } } else{ // three day's weather msg sign[0]=0x01; sign[1]=0x42; sendNum=3; } weathmsg = randWeath(); dayNum = recvline->lineTail; sendline = makeMsg(weathmsg,recvline->city,dayNum,sign,sendNum); send(connfd,(char*)&sendline,sizeof(sendline),0); printf("send a weather forecast message to the client %d...\n",count); } /*proessingh*/ memset(recvline,0,strlen((char*)recvline)); memset(buf,0,MAXLINE); } if(n<0){ printf("%s\n", "read error"); } printf("Connect %d terminated... \n", count); exit(0); } close(connfd); } }
static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (argumentCount < 1) return JSValueMakeUndefined(context); static JSStringRef ctrlKey = JSStringCreateWithUTF8CString("ctrlKey"); static JSStringRef shiftKey = JSStringCreateWithUTF8CString("shiftKey"); static JSStringRef altKey = JSStringCreateWithUTF8CString("altKey"); static JSStringRef metaKey = JSStringCreateWithUTF8CString("metaKey"); static JSStringRef lengthProperty = JSStringCreateWithUTF8CString("length"); COMPtr<IWebFramePrivate> framePrivate; if (SUCCEEDED(frame->QueryInterface(&framePrivate))) framePrivate->layout(); JSStringRef character = JSValueToStringCopy(context, arguments[0], exception); ASSERT(!exception || !*exception); int charCode = JSStringGetCharactersPtr(character)[0]; int virtualKeyCode = toupper(LOBYTE(VkKeyScan(charCode))); JSStringRelease(character); // Hack to map option-delete to ctrl-delete // Remove this when we fix <rdar://problem/5102974> layout tests need a way to decide how to choose the appropriate modifier keys bool convertOptionToCtrl = false; if (virtualKeyCode == VK_DELETE || virtualKeyCode == VK_BACK) convertOptionToCtrl = true; BYTE keyState[256]; if (argumentCount > 1) { ::GetKeyboardState(keyState); BYTE newKeyState[256]; memcpy(newKeyState, keyState, sizeof(keyState)); JSObjectRef modifiersArray = JSValueToObject(context, arguments[1], exception); if (modifiersArray) { int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty, 0), 0); for (int i = 0; i < modifiersCount; ++i) { JSValueRef value = JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0); JSStringRef string = JSValueToStringCopy(context, value, 0); if (JSStringIsEqual(string, ctrlKey)) newKeyState[VK_CONTROL] = 0x80; else if (JSStringIsEqual(string, shiftKey)) newKeyState[VK_SHIFT] = 0x80; else if (JSStringIsEqual(string, altKey)) { if (convertOptionToCtrl) newKeyState[VK_CONTROL] = 0x80; else newKeyState[VK_MENU] = 0x80; } else if (JSStringIsEqual(string, metaKey)) newKeyState[VK_MENU] = 0x80; JSStringRelease(string); } } ::SetKeyboardState(newKeyState); } MSG msg = makeMsg(webViewWindow, WM_KEYDOWN, virtualKeyCode, 0); dispatchMessage(&msg); if (argumentCount > 1) ::SetKeyboardState(keyState); return JSValueMakeUndefined(context); }