Ejemplo n.º 1
0
Archivo: alock.c Proyecto: mgumz/alock
static int eventLoop(struct aOpts* opts, struct aXInfo* xi) {

    Display* dpy = xi->display;
    XEvent ev;
    KeySym ks;
    char cbuf[10];
    char rbuf[50];
    unsigned int clen, rlen = 0;
    long current_time = 0;
    long last_key_time = 0;
    const long penalty = 1000;
    long timeout = 0;
    int mode = INITIAL;

    struct aFrame* frame = alock_create_frame(xi, 0, 0, xi->width_of_root[0], xi->height_of_root[0], 10);

    for(;;) {

        current_time = elapsedTime();

        // check for any keypresses
        if (XCheckWindowEvent(dpy, xi->window[0], KeyPressMask|KeyReleaseMask, &ev) == True) {

            switch (ev.type) {
            case KeyPress:

                last_key_time = current_time;

                if (last_key_time < timeout) {
                    XBell(dpy, 0);
                    break;
                }

                // swallow up first keypress to indicate "enter mode"
                if (mode == INITIAL) {
                    mode = TYPING;
                    break;
                }

                mode = TYPING;

                clen = XLookupString(&ev.xkey, cbuf, 9, &ks, 0);
                switch (ks) {
                case XK_Escape:
                case XK_Clear:
                    rlen = 0;
                    break;
                case XK_Delete:
                case XK_BackSpace:
                    if (rlen > 0)
                        rlen--;
                    break;
                case XK_Linefeed:
                case XK_Return:
                    if (rlen == 0)
                        break;
                    if (rlen < sizeof(rbuf))
                        rbuf[rlen] = 0;

                    // some auth() methods have their own penalty system
                    // so we draw a 'yellow' frame to show 'checking' state.

                    alock_draw_frame(frame, "yellow");
                    XSync(dpy, True);

                    if (opts->auth->auth(rbuf)) {
                        alock_free_frame(frame);
                        return 1;
                    }

                    XBell(dpy, 0);
                    mode = WRONG;
                    timeout = elapsedTime() + penalty;
                    rlen = 0;
                    break;

                default:
                    if (clen != 1)
                        break;
                    if (rlen < (sizeof(rbuf) - 1)) {
                        rbuf[rlen] = cbuf[0];
                        rlen++;
                    }
                    break;
                }
                break;
            case Expose: {
                    XExposeEvent* eev = (XExposeEvent*)&ev;
                    XClearWindow(xi->display, eev->window);
                }
                break;
            default:
                break;
            }

        } else { // wait a bit

            long delta = current_time - last_key_time;

            if (mode == TYPING && (delta > 10000)) { // user fell asleep while typing .)
                mode = INITIAL;
            } else if (mode == WRONG && (current_time > timeout)) { // end of timeout for wrong password
                mode = TYPING;
                last_key_time = timeout; // start 'idle' timer correctly by a fake keypress
            }

            visualFeedback(frame, mode);

            poll(NULL, 0, 25);
        }

    }

    // normally, we shouldnt arrive here at all
    alock_free_frame(frame);
    return 0;
}
Ejemplo n.º 2
0
static int eventLoop(struct aOpts* opts, struct aXInfo* xi)
{

	Display* dpy = xi->display;
	KeySym ks;
	XEvent ev;
	char cbuf[30];
	unsigned int clen, rlen = 0;
	long current_time = 0;
	long last_key_time = 0;
	const long penalty = 1000;
	long timeout = 0;
	int toggle = 0;
	int mode = INITIAL;
	char nameref[STRING_LIMIT];
	char pwdref[STRING_LIMIT];
	char shpwdref[STRING_LIMIT];
	int i = 0;
	int revert = 0;
	int tabpos = -1;
	char * const argv[] =
		{ "/usr/bin/gnome-screensaver-command", "-l", NULL };

	char * const focus[] =
		{ nameref, pwdref, NULL };

	for (i = 0; i < STRING_LIMIT; i++)
	{
		nameref[i] = 0;
		pwdref[i] = 0;
		shpwdref[i] = 0;
	}

	LOG("create visual response frame");
	struct aFrame* frame = tlock_create_frame(xi, 0, 0, xi->width_of_root[0], xi->height_of_root[0], 10);
	LOG("enter dialog creation");
	struct aDialog* dialog = tlock_create_dialog(xi, 50, 50, 320, 110, 10);
	LOG("completed dialog creation");LOG("entering event loop");

	for (;;)
	{
		current_time = elapsedTime();

		// check for any keypresses
		if (XCheckWindowEvent(xi->display, xi->window[0],
		KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask, &ev) == True)
		{
			DEBUG_EVENT_LOOP_BLANK;
			//PRINT(fprintf(stderr, "event.type %d \n", ev.xany.type);)
			switch (ev.xany.type) {
				case KeyPress:
				{

					last_key_time = current_time;

					if (last_key_time < timeout)
					{
						XBell(dpy, 0);
						break;
					}

					// swallow up first keypress to indicate "enter mode"
					if (mode == INITIAL)
					{
						mode = TYPING;
						break;
					}

					mode = TYPING;
					clen = XLookupString(&ev.xkey, cbuf, 15, &ks, 0);
					_PRINTF_( "key=%c \n", cbuf[0]);
					switch (ks) {
						case XK_Tab:

							// if previous tab
							// store previous
							tabpos++;
							if (tabpos > 1)
							{
								tabpos = 0;
							}
							rlen = strlen(focus[tabpos]);
							flag_redraw(dialog);
							_PRINTF_( "TAB_: tabpos = %d, %d = %s\n", tabpos, rlen, focus[tabpos] );
							visualFeedback(xi, dialog, frame, mode, toggle, nameref, shpwdref);
							break;
						case XK_Escape:
						case XK_Clear:
							rlen = 0;
							CLEAN_TAB_ENTRY(tabpos)
							;
							flag_redraw(dialog);
							visualFeedback(xi, dialog, frame, mode, toggle, nameref, shpwdref);
							break;
						case XK_Delete:
						case XK_BackSpace:
							if (tabpos >= 0 && rlen > 0)
							{
								focus[tabpos][rlen] = 0;
								if (tabpos == 1 ){
									shpwdref[rlen] = 0;
								}
								rlen--;
								focus[tabpos][rlen] = 0;
								if (tabpos == 1 ){
									shpwdref[rlen] = 0;
								}
							}
							flag_redraw(dialog);
							visualFeedback(xi, dialog, frame, mode, toggle, nameref, shpwdref);
							_PRINTF_("BACK: tabpos = %d, %d = %s\n", tabpos, rlen, focus[tabpos] );

							break;
						case XK_Linefeed:
						case XK_Return:
							if (tabpos >= 0 && rlen == 0)
							{
								CLEAN_TAB_ENTRY(tabpos);
								break;
							}
							// if nothing was entered and enter/return was
							// pressed, clear buffer and exit out of routine.
							if (tabpos < 0) {
								CLEAN_TAB_ENTRY(0);
								CLEAN_TAB_ENTRY(1);
								break;
							}

							if (rlen < sizeof(focus[tabpos])) {
								focus[tabpos][rlen] = 0;
								if (tabpos == 1) {
									shpwdref[rlen] = 0;
								}
							}

							// some auth() methods have their own penalty system
							// so we draw a 'yellow' frame to show 'checking' state.
							DEBUG_EVENT_LOOP_BLANK;

							tlock_draw_frame(xi, frame, "yellow");
							DEBUG_EVENT_LOOP_BLANK;

							XSync(dpy, True);
							DEBUG_EVENT_LOOP_BLANK;

							// copy buffer in focussed value array
							if (challenge_response_feedback(opts, xi, frame, nameref, pwdref))
							{
								return 1;
							} else
							{
								flag_redraw(dialog);
							}
							//
							CLEAN_TAB_ENTRY(tabpos)
							;
							//XBell(dpy, 0);

							DEBUG_EVENT_LOOP_BLANK;
							mode = WRONG;
							timeout = elapsedTime() + penalty;

							break;

						default:
							if (clen != 1)
								break;
							_PRINTF_("%d, len=%l, f=%l\n", tabpos, rlen, sizeof(nameref));
							if (tabpos >= 0 && rlen < (sizeof(nameref) - 1))
							{
								focus[tabpos][rlen] = cbuf[0];
								if (tabpos == 1) {
									shpwdref[rlen]='*';
								}
								_PRINTF_("%d,  focus=%s\n", tabpos, focus[tabpos]);
								rlen++;
							}
							break;
					}
				}
					break;
				case Expose:
				{
					XExposeEvent* eev = (XExposeEvent*) &ev;
					_PRINTF_( "expose event %d\n", eev->type);
					XClearWindow(xi->display, eev->window);
					exit(400);
				}
					break;
				case ButtonPress:
				{
				}
					break;
				case ButtonRelease:
				{
					// reset the focus position to unknown.
					if (BUTTON_PRESSED("user_field"))
					{
						// if current tab pos != user_field
						// store its value in the right pointer
						tabpos = 0;
					} else
					{
						if (BUTTON_PRESSED("password_field"))
						{
							// if current tab pos != user_field
							// store its value in the right pointer
							tabpos = 1;
						} else
						{
							if (BUTTON_PRESSED("cancel_button"))
							{
								tabpos = -1;
								tabpos = -1;
								CLEAN_TAB_ENTRY(0);
								CLEAN_TAB_ENTRY(1);
								///
								// reset mode for loop event
								mode = INITIAL;
								visualFeedback(xi, dialog, frame, mode, toggle, nameref, shpwdref);
//								syslog(
//								LOG_NOTICE, "switch_button release detected\n");
//								int ret = execvp("gnome-screensaver-command", argv);
//								syslog(
//								LOG_NOTICE, "Return not expected. Must be an execvp() error [exit=%d].\n", ret);
//								exit(0);

							} else
							{
								if (BUTTON_PRESSED("clear_button"))
								{
									tabpos = -1;
									CLEAN_TAB_ENTRY(0);
									CLEAN_TAB_ENTRY(1);
									///
									// reset mode for loop event
									mode = TYPING;
									visualFeedback(xi, dialog, frame, mode, toggle, nameref, shpwdref);
								}
							}
						}
					}
				} // case BUTTON RELEASE end
					break;
				default:
					break;
			}DEBUG_EVENT_LOOP_BLANK;

		} else
		{ // wait a bit
			DEBUG_EVENT_LOOP_BLANK;
			long delta = current_time - last_key_time;

			if (mode == TYPING && (delta > 10000))
			{ // user fell asleep while typing .)
				mode = INITIAL;
			} else
				if (mode == WRONG && (current_time > timeout))
				{ // end of timeout for wrong password
					mode = TYPING;
					last_key_time = timeout; // start 'idle' timer correctly by a fake keypress
				}

			if (delta > 1000)
			{
				toggle = 2;
				if (opts->flash) {
					toggle = (delta / 1000) % 2;
				}
			}DEBUG_EVENT_LOOP_BLANK;

			visualFeedback(xi, dialog, frame, mode, toggle, nameref, shpwdref);
			DEBUG_EVENT_LOOP_BLANK;

			poll(NULL, 0, 25);
		}

	}

// normally, we shouldn't arrive here at all
	tlock_free_frame(xi, frame);
#ifdef HAVE_DIALOG
	tlock_free_dialog(xi, dialog);
#endif
	return 0;
}