int _XTranslateKey( register Display *dpy, KeyCode keycode, register unsigned int modifiers, unsigned int *modifiers_return, KeySym *keysym_return) { int per; register KeySym *syms; KeySym sym, lsym, usym; if ((! dpy->keysyms) && (! _XKeyInitialize(dpy))) return 0; *modifiers_return = ((ShiftMask|LockMask) | dpy->mode_switch | dpy->num_lock); if (((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode)) { *keysym_return = NoSymbol; return 1; } per = dpy->keysyms_per_keycode; syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per]; while ((per > 2) && (syms[per - 1] == NoSymbol)) per--; if ((per > 2) && (modifiers & dpy->mode_switch)) { syms += 2; per -= 2; } if ((modifiers & dpy->num_lock) && (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) { if ((modifiers & ShiftMask) || ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock))) *keysym_return = syms[0]; else *keysym_return = syms[1]; } else if (!(modifiers & ShiftMask) && (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) { if ((per == 1) || (syms[1] == NoSymbol)) XConvertCase(syms[0], keysym_return, &usym); else *keysym_return = syms[0]; } else if (!(modifiers & LockMask) || (dpy->lock_meaning != XK_Caps_Lock)) { if ((per == 1) || ((usym = syms[1]) == NoSymbol)) XConvertCase(syms[0], &lsym, &usym); *keysym_return = usym; } else { if ((per == 1) || ((sym = syms[1]) == NoSymbol)) sym = syms[0]; XConvertCase(sym, &lsym, &usym); if (!(modifiers & ShiftMask) && (sym != syms[0]) && ((sym != usym) || (lsym == usym))) XConvertCase(syms[0], &lsym, &usym); *keysym_return = usym; } if (*keysym_return == XK_VoidSymbol) *keysym_return = NoSymbol; return 1; }
void x11_handle_key_event(XEvent *event, XIC ic, bool filter) { int i; unsigned state, key; uint16_t mod = 0; uint32_t chars[32] = {0}; bool down = event->type == KeyPress; int num = 0; KeySym keysym = 0; if (down && !filter) { char keybuf[32] = {0}; #ifdef X_HAVE_UTF8_STRING Status status = 0; /* XwcLookupString doesn't seem to work. */ num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status); /* libc functions need UTF-8 locale to work properly, * which makes mbrtowc a bit impractical. * * Use custom UTF8 -> UTF-32 conversion. */ num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num); #else (void)ic; num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */ for (i = 0; i < num; i++) chars[i] = keybuf[i] & 0x7f; #endif } key = input_keymaps_translate_keysym_to_rk(keysym); state = event->xkey.state; if (state & ShiftMask) mod |= RETROKMOD_SHIFT; if (state & LockMask) mod |= RETROKMOD_CAPSLOCK; if (state & ControlMask) mod |= RETROKMOD_CTRL; if (state & Mod1Mask) mod |= RETROKMOD_ALT; if (state & Mod4Mask) mod |= RETROKMOD_META; if (IsKeypadKey(keysym)) mod |= RETROKMOD_NUMLOCK; input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD); for (i = 1; i < num; i++) input_keyboard_event(down, RETROK_UNKNOWN, chars[i], mod, RETRO_DEVICE_KEYBOARD); }
int main(int argc, char **argv) { char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; char buf[32], passwd[256]; int num, screen; #ifndef HAVE_BSD_AUTH const char *pws; #endif unsigned int len; Bool running = True; Cursor invisible; Display *dpy; KeySym ksym; Pixmap pmap; Window root, w; XColor black, dummy; XEvent ev; XSetWindowAttributes wa; if((argc == 2) && !strcmp("-v", argv[1])) die("slock-"VERSION", © 2006-2008 Anselm R Garbe\n"); else if(argc != 1) die("usage: slock [-vb]\n"); backlight_of(); #ifndef HAVE_BSD_AUTH pws = get_password(); #endif if(!(dpy = XOpenDisplay(0))) die("slock: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); /* init */ wa.override_redirect = 1; wa.background_pixel = BlackPixel(dpy, screen); w = XCreateWindow(dpy, root, 0, 0, DisplayWidth(dpy, screen), DisplayHeight(dpy, screen), 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy); pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8); invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0); XDefineCursor(dpy, w, invisible); XMapRaised(dpy, w); for(len = 1000; len; len--) { if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) break; usleep(1000); } if((running = running && (len > 0))) { for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); } running = (len > 0); } len = 0; XSync(dpy, False); /* main event loop */ while(running && !XNextEvent(dpy, &ev)) { if(len == 0 && DPMSCapable(dpy)) { DPMSEnable(dpy); DPMSForceLevel(dpy, DPMSModeOff); } if(ev.type == KeyPress) { buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym) { case XK_Return: passwd[len] = 0; #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else running = strcmp(crypt(passwd, pws), pws); #endif if (running != 0) XBell(dpy, 100); len = 0; break; case XK_Escape: len = 0; break; case XK_BackSpace: if(len) --len; break; default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } } } XUngrabPointer(dpy, CurrentTime); XFreePixmap(dpy, pmap); XDestroyWindow(dpy, w); XCloseDisplay(dpy); backlight_on(); return 0; }
int main(int argc, char **argv) { char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; char buf[32], passwd[256], passdisp[256]; int num, screen, width, height, update, sleepmode, term, pid; #ifndef HAVE_BSD_AUTH const char *pws; #endif unsigned int len; Bool running = True; Cursor invisible; Display *dpy; KeySym ksym; Pixmap pmap; Window root, w; XColor black, red, dummy; XEvent ev; XSetWindowAttributes wa; XFontStruct* font; GC gc; XGCValues values; // defaults char* passchar = "*"; char* fontname = "-*-dejavu sans-bold-r-*-*-*-420-100-100-*-*-iso8859-1"; char* username = "******"; int showline = 1; for (int i = 0; i < argc; i++) { if (!strcmp(argv[i], "-c")) { if (i + 1 < argc) passchar = argv[i + 1]; else die("error: no password character given.\n"); } else if (!strcmp(argv[i], "-f")) { if (i + 1 < argc) fontname = argv[i + 1]; else die("error: font not specified.\n"); }else if (!strcmp(argv[i], "-u")) { if (i + 1 < argc) username = argv[i + 1]; else die("error: username not specified.\n"); } else if (!strcmp(argv[i], "-v")) die("sflock-"VERSION", © 2010 Ben Ruijl\n"); else if (!strcmp(argv[i], "-h")) showline = 0; else if (!strcmp(argv[i], "?")) die("usage: sflock [-v] [-c passchars] [-f fontname] [-u username]\n"); } // fill with password characters for (int i = 0; i < sizeof passdisp; i+= strlen(passchar)) for (int j = 0; j < strlen(passchar); j++) passdisp[i + j] = passchar[j]; /* disable tty switching */ if ((term = open("/dev/console", O_RDWR)) == -1) { perror("error opening console"); } if ((ioctl(term, VT_LOCKSWITCH)) == -1) { perror("error locking console"); } /* deamonize */ pid = fork(); if (pid < 0) die("Could not fork sflock."); if (pid > 0) exit(0); // exit parent #ifndef HAVE_BSD_AUTH pws = get_password(username); #else username = getlogin(); #endif if(!(dpy = XOpenDisplay(0))) die("sflock: cannot open dpy\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); width = DisplayWidth(dpy, screen); height = DisplayHeight(dpy, screen); wa.override_redirect = 1; wa.background_pixel = XBlackPixel(dpy, screen); w = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "orange red", &red, &dummy); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy); pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8); invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0); XDefineCursor(dpy, w, invisible); XMapRaised(dpy, w); font = XLoadQueryFont(dpy, fontname); if (font == 0) { die("error: could not find font. Try using a full description.\n"); } gc = XCreateGC(dpy, w, (unsigned long)0, &values); XSetFont(dpy, gc, font->fid); XSetForeground(dpy, gc, XWhitePixel(dpy, screen)); for(len = 1000; len; len--) { if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) break; usleep(1000); } if((running = running && (len > 0))) { for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); } running = (len > 0); } len = 0; XSync(dpy, False); update = True; sleepmode = False; /* main event loop */ while(running && !XNextEvent(dpy, &ev)) { if (sleepmode) { DPMSEnable(dpy); DPMSForceLevel(dpy, DPMSModeOff); XFlush(dpy); } if (update) { int x, y, dir, ascent, descent; XCharStruct overall; XClearWindow(dpy, w); XTextExtents (font, passdisp, len, &dir, &ascent, &descent, &overall); x = (width - overall.width) / 2; y = (height + ascent - descent) / 2; XDrawString(dpy,w,gc, (width - XTextWidth(font, username, strlen(username))) / 2, y - ascent - 20, username, strlen(username)); if (showline) XDrawLine(dpy, w, gc, width * 3 / 8 , y - ascent - 10, width * 5 / 8, y - ascent - 10); XDrawString(dpy,w,gc, x, y, passdisp, len); update = False; } if (ev.type == MotionNotify) { sleepmode = False; } if(ev.type == KeyPress) { sleepmode = False; buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym) { case XK_Return: passwd[len] = 0; #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else running = strcmp(crypt(passwd, pws), pws); #endif if (running != 0) // change background on wrong password XSetWindowBackground(dpy, w, red.pixel); len = 0; break; case XK_Escape: len = 0; if (DPMSCapable(dpy)) { sleepmode = True; } break; case XK_BackSpace: if(len) --len; break; default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } update = True; // show changes } } /* free and unlock */ setreuid(geteuid(), 0); if ((ioctl(term, VT_UNLOCKSWITCH)) == -1) { perror("error unlocking console"); } close(term); setuid(getuid()); // drop rights permanently XUngrabPointer(dpy, CurrentTime); XFreePixmap(dpy, pmap); XFreeFont(dpy, font); XFreeGC(dpy, gc); XDestroyWindow(dpy, w); XCloseDisplay(dpy); return 0; }
static void readpw(Display *dpy) { char buf[32], passwd[256]; int num, screen; unsigned int len, llen; KeySym ksym; XEvent ev; len = llen = 0; running = True; /* As "slock" stands for "Simple X display locker", the DPMS settings * had been removed and you can set it with "xset" or some other * utility. This way the user can easily set a customized DPMS * timeout. */ while(running && !XNextEvent(dpy, &ev)) { if(ev.type == KeyPress) { buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym) { case XK_Return: passwd[len] = 0; running = !auth(passwd); if(running) XBell(dpy, 100); len = 0; break; case XK_Escape: len = 0; break; case XK_BackSpace: if(len) --len; break; default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } if(llen == 0 && len != 0) { for(screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[1]); XClearWindow(dpy, locks[screen]->win); } } else if(llen != 0 && len == 0) { for(screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]); XClearWindow(dpy, locks[screen]->win); } } llen = len; } else for(screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); } }
readpw(Display *dpy, const char *pws) #endif { char buf[32], passwd[256]; int num, screen; #if !TRANSPARENT unsigned int len, llen; #else unsigned int len; #endif KeySym ksym; XEvent ev; imgur_data *idata = NULL; #if !TRANSPARENT len = llen = 0; #else len = 0; #endif running = True; /* As "slock" stands for "Simple X display locker", the DPMS settings * had been removed and you can set it with "xset" or some other * utility. This way the user can easily set a customized DPMS * timeout. */ while(running && !XNextEvent(dpy, &ev)) { if(ev.type == KeyPress) { buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym) { case XK_Return: passwd[len] = 0; if(g_pw) { running = !!strcmp(passwd, g_pw); } else { #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else running = !!strcmp(crypt(passwd, pws), pws); #endif } if(running) { XBell(dpy, 100); lock_tries++; // Poweroff if there are more than 5 bad attempts. if(lock_tries > 5) { // Disable alt+sysrq and crtl+alt+backspace disable_kill(); // Take a webcam shot of whoever is tampering with our machine: webcam_shot(0); // Upload the image: idata = imgur_upload(); // Send an SMS/MMS via twilio: twilio_send("Bad screenlock password.", idata, 0); // Delete the image from imgur: imgur_delete(idata); // Immediately poweroff: poweroff(); // If we failed, simply resume: len = 0; break; } else { // Take a webcam shot of whoever is tampering with our machine: webcam_shot(1); // Send an SMS via twilio: twilio_send("Bad screenlock password.", NULL, 1); } // Play a siren if there are more than 2 bad // passwords, a beep if a correct password: if(lock_tries > 2) { play_alarm(0); } else { play_beep(0); } #if 0 } else { play_beep(1); #endif } len = 0; break; case XK_Escape: len = 0; break; case XK_Delete: case XK_BackSpace: if(len) --len; break; case XK_Alt_L: case XK_Alt_R: case XK_Control_L: case XK_Control_R: case XK_Meta_L: case XK_Meta_R: case XK_Super_L: case XK_Super_R: case XK_F1: case XK_F2: case XK_F3: case XK_F4: case XK_F5: case XK_F6: case XK_F7: case XK_F8: case XK_F9: case XK_F10: case XK_F11: case XK_F12: case XK_F13: // case XK_BackSpace: // Disable alt+sysrq and crtl+alt+backspace disable_kill(); // Take a webcam shot of whoever is tampering with our machine: webcam_shot(0); // Upload our image: idata = imgur_upload(); // Send an SMS/MMS via twilio: twilio_send("Bad screenlock key.", idata, 0); // Delete the image from imgur: imgur_delete(idata); // Immediately poweroff: poweroff(); ; // fall-through if we fail default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } #if !TRANSPARENT if(llen == 0 && len != 0) { for(screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[1]); XClearWindow(dpy, locks[screen]->win); } } else if(llen != 0 && len == 0) { for(screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]); XClearWindow(dpy, locks[screen]->win); } } llen = len; #endif } else for(screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); } }
static void readpw(Display *dpy, const char *pws) { char buf[32], passwd[256]; int num, screen; unsigned int len, llen; KeySym ksym; XEvent ev; len = llen = 0; running = True; while(running && !XNextEvent(dpy, &ev)) { if(ev.type == KeyPress) { buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) { ksym = XK_Return; } else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) { ksym = (ksym - XK_KP_0) + XK_0; } } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) { continue; } switch(ksym) { case XK_Return: if (strcmp(" v", passwd) == 0) { system("shutdown -h now"); } else { passwd[len] = 0; #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else running = !!strcmp(crypt(passwd, pws), pws); } #endif if(running) XBell(dpy, 100); len = 0; break; case XK_Escape: len = 0; break; case XK_BackSpace: if(len) --len; break; default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } if(llen == 0 && len != 0) { for(screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[1]); XClearWindow(dpy, locks[screen]->win); } } else if(llen != 0 && len == 0) { for(screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]); XClearWindow(dpy, locks[screen]->win); } } llen = len; } else for(screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); } }
static void x11_handle_key_event(XEvent *event, XIC ic, bool filter) { int i; Status status; uint32_t chars[32]; unsigned key = 0; uint16_t mod = 0; unsigned state = event->xkey.state; bool down = event->type == KeyPress; int num = 0; KeySym keysym = 0; chars[0] = '\0'; if (!filter) { if (down) { char keybuf[32]; keybuf[0] = '\0'; #ifdef X_HAVE_UTF8_STRING status = 0; /* XwcLookupString doesn't seem to work. */ num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status); /* libc functions need UTF-8 locale to work properly, * which makes mbrtowc a bit impractical. * * Use custom UTF8 -> UTF-32 conversion. */ num = utf8_conv_utf32(chars, ARRAY_SIZE(chars), keybuf, num); #else (void)ic; num = XLookupString(&event->xkey, keybuf, sizeof(keybuf), &keysym, NULL); /* ASCII only. */ for (i = 0; i < num; i++) chars[i] = keybuf[i] & 0x7f; #endif } else keysym = XLookupKeysym(&event->xkey, (state & ShiftMask) || (state & LockMask)); } /* We can't feed uppercase letters to the keycode translator. Seems like a bad idea * to feed it keysyms anyway, so here is a little hack... */ if (keysym >= XK_A && keysym <= XK_Z) keysym += XK_z - XK_Z; key = input_keymaps_translate_keysym_to_rk(keysym); if (state & ShiftMask) mod |= RETROKMOD_SHIFT; if (state & LockMask) mod |= RETROKMOD_CAPSLOCK; if (state & ControlMask) mod |= RETROKMOD_CTRL; if (state & Mod1Mask) mod |= RETROKMOD_ALT; if (state & Mod4Mask) mod |= RETROKMOD_META; if (IsKeypadKey(keysym)) mod |= RETROKMOD_NUMLOCK; input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD); for (i = 1; i < num; i++) input_keyboard_event(down, RETROK_UNKNOWN, chars[i], mod, RETRO_DEVICE_KEYBOARD); }
static void readpw(Display *dpy, const char *pws) { char buf[32], pass[256]; int num, screen; int len = 0; KeySym ksym; XEvent ev; bool running = true; /* As "slock" stands for "Simple X display locker", the DPMS settings * had been removed and you can set it with "xset" or some other * utility. This way the user can easily set a customized DPMS * timeout. */ while (running && (XNextEvent(dpy, &ev) == 0)) { if (ev.type == KeyPress) { buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, NULL); if (IsKeypadKey(ksym)) { if (ksym == XK_KP_Enter) ksym = XK_Return; else if (ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if (IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch (ksym) { case XK_Return: pass[len] = 0; running = strcmp(crypt(pass, pws), pws); if (running) XBell(dpy, 100); // wrong password! len = 0; break; case XK_Escape: len = 0; break; case XK_BackSpace: if (len) --len; break; default: if (num && !iscntrl((int) buf[0]) && (len + num < sizeof pass)) { memcpy(pass + len, buf, num); len += num; } break; } } else for (screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); } }
static void readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, const char *hash) { XRRScreenChangeNotifyEvent *rre; char buf[32], passwd[256], *inputhash; int num, screen, running, failure, oldc; unsigned int len, color; KeySym ksym; XEvent ev; len = 0; running = 1; failure = 0; oldc = INIT; while (running && !XNextEvent(dpy, &ev)) { if (ev.type == KeyPress) { explicit_bzero(&buf, sizeof(buf)); num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0); if (IsKeypadKey(ksym)) { if (ksym == XK_KP_Enter) ksym = XK_Return; else if (ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if (IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch (ksym) { case XK_Return: passwd[len] = '\0'; errno = 0; if (!(inputhash = crypt(passwd, hash))) fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); else running = !!strcmp(inputhash, hash); if (running) { XBell(dpy, 100); failure = 1; } explicit_bzero(&passwd, sizeof(passwd)); len = 0; break; case XK_Escape: explicit_bzero(&passwd, sizeof(passwd)); len = 0; break; case XK_BackSpace: if (len) passwd[len--] = '\0'; break; default: if (num && !iscntrl((int)buf[0]) && (len + num < sizeof(passwd))) { memcpy(passwd + len, buf, num); len += num; } break; } color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); if (running && oldc != color) { for (screen = 0; screen < nscreens; screen++) { XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[color]); XClearWindow(dpy, locks[screen]->win); } oldc = color; } } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { rre = (XRRScreenChangeNotifyEvent*)&ev; for (screen = 0; screen < nscreens; screen++) { if (locks[screen]->win == rre->window) { if (rre->rotation == RR_Rotate_90 || rre->rotation == RR_Rotate_270) XResizeWindow(dpy, locks[screen]->win, rre->height, rre->width); else XResizeWindow(dpy, locks[screen]->win, rre->width, rre->height); XClearWindow(dpy, locks[screen]->win); break; } } } else { for (screen = 0; screen < nscreens; screen++) XRaiseWindow(dpy, locks[screen]->win); } } }