test: keyboard.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# keyboard.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Functions

SHORT | _GetKeyState (int vk)
SHORT | _GetAsyncKeyState (int vk)
BOOL | _SetKeyboardState (CONST BYTE *pb)
VOID | RegisterPerUserKeyboardIndicators (PUNICODE_STRING pProfileUserName)
VOID | UpdatePerUserKeyboardIndicators (PUNICODE_STRING pProfileUserName)
void | UpdateAsyncKeyState (PQ pqOwner, UINT wVK, BOOL fBreak)

## Variables

CONST WCHAR | wszInitialKeyboardIndicators [] = L"InitialKeyboardIndicators"

## Function Documentation

SHORT _GetAsyncKeyState | ( | int | vk | ) |

Definition at line 87 of file keyboard.c.

References ClearAsyncKeyStateRecentDown, CVKKEYSTATE, SHORT, TestAsyncKeyStateDown, TestAsyncKeyStateRecentDown, and UINT.

Referenced by NtUserGetAsyncKeyState(), xxxMNOpenHierarchy(), xxxNextWindow(), xxxPaintIconsInSwitchWindow(), xxxPaintSwitchWindow(), and xxxShowSwitchWindow().

    00089 {
    00090     SHORT sKeyState;
    00091
    00092     if ((UINT)vk >= CVKKEYSTATE) {
    00093         RIPERR1(ERROR_INVALID_PARAMETER,
    00094                 RIP_WARNING,
    00095                 "Invalid parameter \"vk\" (%ld) to _GetAsyncKeyState",
    00096                 vk);
    00097
    00098         return 0;
    00099     }
    00100
    00101     /*
    00102      * See if this key went down since the last time state for it was
    00103      * read. Clear the flag if so.
    00104      */
    00105     sKeyState = 0;
    00106     if (TestAsyncKeyStateRecentDown(vk)) {
    00107         ClearAsyncKeyStateRecentDown(vk);
    00108         sKeyState = 1;
    00109     }
    00110
    00111     /*
    00112      * Set the keyup/down bit.
    00113      */
    00114     if (TestAsyncKeyStateDown(vk))
    00115         sKeyState |= 0x8000;
    00116
    00117     /*
    00118      * Don't return the toggle bit since it's a new bit and might
    00119      * cause compatibility problems.
    00120      */
    00121     return sKeyState;
    00122 }

SHORT _GetKeyState | ( | int | vk | ) |

Definition at line 27 of file keyboard.c.

References CVKKEYSTATE, tagTHREADINFO::pq, PtiCurrentShared, SHORT, TestKeyStateDown, TestKeyStateToggle, and UINT.

Referenced by InitSwitchWndInfo(), MNCheckButtonDownState(), NtUserGetKeyState(), xxxDefWindowProc(), xxxIsDragging(), xxxMNLoop(), xxxMNStartMenu(), xxxMS_TrackMove(), xxxOldNextWindow(), xxxPaintIconsInSwitchWindow(), xxxPaintSwitchWindow(), xxxSBWndProc(), xxxShowSwitchWindow(), xxxSysCommand(), xxxTrackPopupMenuEx(), xxxTrackThumb(), and xxxTranslateAccelerator().

    00029 {
    00030     UINT wKeyState;
    00031     PTHREADINFO pti;
    00032
    00033     if ((UINT)vk >= CVKKEYSTATE) {
    00034         RIPERR1(ERROR_INVALID_PARAMETER,
    00035                 RIP_WARNING,
    00036                 "Invalid parameter \"vk\" (%ld) to _GetKeyState",
    00037                 vk);
    00038
    00039         return 0;
    00040     }
    00041
    00042     pti = PtiCurrentShared();
    00043
    00044 #ifdef LATER
    00045 //
    00046 // note - anything that accesses the pq structure is a bad idea since it
    00047 // can be changed between any two instructions.
    00048 //
    00049 #endif
    00050
    00051     wKeyState = 0;
    00052
    00053     /*
    00054      * Set the toggle bit.
    00055      */
    00056     if (TestKeyStateToggle(pti->pq, vk))
    00057         wKeyState = 0x0001;
    00058
    00059     /*
    00060      * Set the keyup/down bit.
    00061      */
    00062     if (TestKeyStateDown(pti->pq, vk)) {
    00063         /*
    00064          * Used to be wKeyState|= 0x8000.Fix for bug 28820; Ctrl-Enter
    00065          * accelerator doesn't work on Nestscape Navigator Mail 2.0
    00066          */
    00067         wKeyState |= 0xff80;  // This is what 3.1 returned!!!!
    00068     }
    00069
    00070     return (SHORT)wKeyState;
    00071 }

BOOL _SetKeyboardState | ( | CONST BYTE * | pb | ) |

Definition at line 136 of file keyboard.c.

References BOOL, ClearAsyncKeyStateToggle, ClearKeyStateDown, ClearKeyStateToggle, gpsi, tagTHREADINFO::pq, PtiCurrent, SetAsyncKeyStateToggle, SetKeyStateDown, SetKeyStateToggle, TRUE, and UpdateKeyLights().

Referenced by NtUserSetKeyboardState().

    00138 {
    00139     int i;
    00140     PQ pq;
    00141     PTHREADINFO  ptiCurrent = PtiCurrent();
    00142
    00143     pq = ptiCurrent->pq;
    00144
    00145     /*
    00146      * Copy in the new state table.
    00147      */
    00148     for (i = 0; i < 256; i++, pb++) {
    00149         if (*pb & 0x80) {
    00150             SetKeyStateDown(pq, i);
    00151         } else {
    00152             ClearKeyStateDown(pq, i);
    00153         }
    00154
    00155         if (*pb & 0x01) {
    00156             SetKeyStateToggle(pq, i);
    00157         } else {
    00158             ClearKeyStateToggle(pq, i);
    00159         }
    00160     }
    00161
    00162     /*
    00163      * Update the key cache index.
    00164      */
    00165     gpsi->dwKeyCache++;
    00166
    00167 #ifdef LATER
    00168 // scottlu 6-9-91
    00169 // I don't think we ought to do this unless someone really complains. This
    00170 // could have bad side affects, especially considering that terminal
    00171 // apps will want to do this, and terminal apps could easily not respond
    00172 // to input for awhile, causing this state to change unexpectedly while
    00173 // a user is using some other application. - scottlu.
    00174
    00175 /* DavidPe 02/05/92
    00176  *  How about if we only do it when the calling app is foreground?
    00177  */
    00178
    00179     /*
    00180      * Propagate the toggle bits for the keylight keys to the
    00181      * async keystate table and update the keylights.
    00182      *
    00183      * THIS could be evil in a de-synced environment, but to do this
    00184      * in a totally "synchronous" way is hard.
    00185      */
    00186     if (pb[VK_CAPITAL] & 0x01) {
    00187         SetAsyncKeyStateToggle(VK_CAPITAL);
    00188     } else {
    00189         ClearAsyncKeyStateToggle(VK_CAPITAL);
    00190     }
    00191
    00192     if (pb[VK_NUMLOCK] & 0x01) {
    00193         SetAsyncKeyStateToggle(VK_NUMLOCK);
    00194     } else {
    00195         ClearAsyncKeyStateToggle(VK_NUMLOCK);
    00196     }
    00197
    00198     if (pb[VK_SCROLL] & 0x01) {
    00199         SetAsyncKeyStateToggle(VK_SCROLL);
    00200     } else {
    00201         ClearAsyncKeyStateToggle(VK_SCROLL);
    00202     }
    00203
    00204     UpdateKeyLights(TRUE);
    00205 #endif
    00206
    00207     return TRUE;
    00208 }

VOID RegisterPerUserKeyboardIndicators | ( | PUNICODE_STRING | pProfileUserName | ) |

Definition at line 223 of file keyboard.c.

References FastWriteProfileStringW(), ISTS, L, PMAP_KEYBOARD, TestAsyncKeyStateToggle, and wszInitialKeyboardIndicators.

Referenced by PrepareForLogoff().

    00224 {
    00225     WCHAR wszInitKbdInd[2] = L"0";
    00226
    00227     /*
    00228      * Initial Keyboard state (Num-Lock only)
    00229      */
    00230
    00231     /*
    00232      * For HYDRA we do not want to save this as set, since it confuses
    00233      * dial in laptop computers. So we force it off in the profile on
    00234      * logoff.
    00235      */
    00236     if (!ISTS()) {
    00237         wszInitKbdInd[0] += TestAsyncKeyStateToggle(VK_NUMLOCK) ? 2 : 0;
    00238     }
    00239
    00240     FastWriteProfileStringW(pProfileUserName,
    00241                             PMAP_KEYBOARD,
    00242                             wszInitialKeyboardIndicators,
    00243                             wszInitKbdInd);
    00244 }

void UpdateAsyncKeyState | ( | PQ | pqOwner,
|  | UINT | wVK,
|  | BOOL | fBreak
| ) |

Definition at line 322 of file keyboard.c.

References tagQ::afKeyRecentDown, CheckCritIn, ClearAsyncKeyStateDown, ClearAsyncKeyStateToggle, CVKASYNCKEYCACHE, gpsi, grpdeskRitInput, NULL, PostUpdateKeyStateEvent(), tagTHREADINFO::pq, tagDESKTOP::PtiList, tagQ::QF_flags, QF_UPDATEKEYSTATE, SetAsyncKeyStateDown, SetAsyncKeyStateRecentDown, SetAsyncKeyStateToggle, SetKeyRecentDownBit, TestAsyncKeyStateDown, and TestAsyncKeyStateToggle.

Referenced by xxxButtonEvent(), and xxxKeyEvent().

    00326 {
    00327     PQ pqT;
    00328     PLIST_ENTRY pHead, pEntry;
    00329     PTHREADINFO pti;
    00330
    00331     CheckCritIn();
    00332
    00333     /*
    00334      * First check to see if the queue this key is going to has a pending
    00335      * key state event. If it does, post it because we need to copy the
    00336      * async key state into this event as it is before we modify
    00337      * this key's state, or else we'll generate a key state event with
    00338      * the wrong key state in it.
    00339      */
    00340     if (pqOwner != NULL && pqOwner->QF_flags & QF_UPDATEKEYSTATE) {
    00341         PostUpdateKeyStateEvent(pqOwner);
    00342     }
    00343
    00344     if (!fBreak) {
    00345         /*
    00346          * This key has gone down - update the "recent down" bit in the
    00347          * async key state table.
    00348          */
    00349         SetAsyncKeyStateRecentDown(wVK);
    00350
    00351         /*
    00352          * This is a key make. If the key was not already down, update the
    00353          * toggle bit.
    00354          */
    00355         if (!TestAsyncKeyStateDown(wVK)) {
    00356             if (TestAsyncKeyStateToggle(wVK)) {
    00357                 ClearAsyncKeyStateToggle(wVK);
    00358             } else {
    00359                 SetAsyncKeyStateToggle(wVK);
    00360             }
    00361         }
    00362
    00363         /*
    00364          * This is a make, so turn on the key down bit.
    00365          */
    00366         SetAsyncKeyStateDown(wVK);
    00367
    00368     } else {
    00369         /*
    00370          * This is a break, so turn off the key down bit.
    00371          */
    00372         ClearAsyncKeyStateDown(wVK);
    00373     }
    00374
    00375     /*
    00376      * If this is one of the keys we cache, update the async key cache index.
    00377      */
    00378     if (wVK < CVKASYNCKEYCACHE) {
    00379         gpsi->dwAsyncKeyCache++;
    00380     }
    00381
    00382     /*
    00383      * A key has changed state. Update all queues not receiving this input so
    00384      * they know that this key has changed state. This lets us know which keys to
    00385      * update in the thread specific key state table to keep it in sync
    00386      * with the user.  Walking down the thread list may mean that an
    00387      * individual queue may by updated more than once, but it is cheaper
    00388      * than maintaining a list of queues on the desktop.
    00389      */
    00390     UserAssert(grpdeskRitInput != NULL);
    00391
    00392     pHead = &grpdeskRitInput->PtiList;
    00393     for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
    00394         pti = CONTAINING_RECORD(pEntry, THREADINFO, PtiLink);
    00395
    00396         /*
    00397          * Don't update the queue this message is going to - it'll be
    00398          * in sync because it is receiving this message.
    00399          */
    00400         pqT = pti->pq;
    00401         if (pqT == pqOwner)
    00402             continue;
    00403
    00404         /*
    00405          * Set the "recent down" bit. In this case this doesn't really mean
    00406          * "recent down", it means "recent change" (since the last time
    00407          * we synced this queue), either up or down. This tells us which
    00408          * keys went down since the last time this thread synced with key
    00409          * state. Set the "update key state" flag so we know that later
    00410          * we need to sync with these keys.
    00411          */
    00412         SetKeyRecentDownBit(pqT->afKeyRecentDown, wVK);
    00413         pqT->QF_flags |= QF_UPDATEKEYSTATE;
    00414     }
    00415
    00416     /*
    00417      * Update the key cache index.
    00418      */
    00419     gpsi->dwKeyCache++;
    00420 }

VOID UpdatePerUserKeyboardIndicators | ( | PUNICODE_STRING | pProfileUserName | ) |

Definition at line 256 of file keyboard.c.

References ClearAsyncKeyStateToggle, ClearKeyStateToggle, ClearRawKeyToggle, DWORD, FALSE, FastGetProfileIntW(), gbRemoteSession, gfKanaToggle, gklpBootTime, PMAP_KEYBOARD, tagTHREADINFO::pq, PtiCurrent, SetAsyncKeyStateToggle, SetKeyStateToggle, SetRawKeyToggle, UpdateKeyLights(), and wszInitialKeyboardIndicators.

Referenced by xxxUpdatePerUserSystemParameters().

    00257 {
    00258     DWORD dw;
    00259     PQ pq;
    00260     PTHREADINFO  ptiCurrent = PtiCurrent();
    00261     pq = ptiCurrent->pq;
    00262
    00263     /*
    00264      * For terminal server, the client is responsible for synchronizing the
    00265      * keyboard state.
    00266      */
    00267     if (gbRemoteSession) {
    00268         return;
    00269     }
    00270
    00271     /*
    00272      * Initial Keyboard state (Num-Lock only)
    00273      */
    00274     dw = FastGetProfileIntW(pProfileUserName,
    00275                             PMAP_KEYBOARD,
    00276                             wszInitialKeyboardIndicators,
    00277                             2);
    00278
    00279     dw &= 0x80000002;
    00280
    00281
    00282     /*
    00283      * The special value 0x80000000 in the registry indicates that the BIOS
    00284      * settings are to be used as the initial LED state. (This is undocumented)
    00285      */
    00286     if (dw == 0x80000000) {
    00287         dw = gklpBootTime.LedFlags;
    00288     }
    00289     if (dw & 0x02) {
    00290         SetKeyStateToggle(pq, VK_NUMLOCK);
    00291         SetAsyncKeyStateToggle(VK_NUMLOCK);
    00292         SetRawKeyToggle(VK_NUMLOCK);
    00293     } else {
    00294         ClearKeyStateToggle(pq, VK_NUMLOCK);
    00295         ClearAsyncKeyStateToggle(VK_NUMLOCK);
    00296         ClearRawKeyToggle(VK_NUMLOCK);
    00297     }
    00298
    00299     /*
    00300      * Initialize KANA Toggle status
    00301      */
    00302     gfKanaToggle = FALSE;
    00303     ClearKeyStateToggle(pq, VK_KANA);
    00304     ClearAsyncKeyStateToggle(VK_KANA);
    00305     ClearRawKeyToggle(VK_KANA);
    00306
    00307     UpdateKeyLights(FALSE);
    00308 }

## Variable Documentation

CONST WCHAR wszInitialKeyboardIndicators[] = L"InitialKeyboardIndicators"`[static]`

| Definition at line 220 of file keyboard.c. Referenced by RegisterPerUserKeyboardIndicators(), and UpdatePerUserKeyboardIndicators().