Exemple #1
0
int main(int argc, char **argv) {

    struct aXInfo xinfo;
    struct aOpts opts = {
        alock_authmodules[0],
        alock_inputs[0],
        alock_cursors[0],
        alock_backgrounds[0],
    };

#if HAVE_X11_EXTENSIONS_XF86MISC_H
    int xf86misc_major = -1;
    int xf86misc_minor = -1;
#endif

    int arg;
    const char *optarg;
    const char *auth_args = NULL;
    const char *input_args = NULL;
    const char *cursor_args = NULL;
    const char *background_args = NULL;

    /* parse options */
    if (argc > 1) {
        for (arg = 1; arg < argc; arg++) {
            if (!strcmp(argv[arg], "-bg")) {
                optarg = argv[++arg];
                if (optarg != NULL) {

                    struct aBackground **i;
                    if (strcmp(optarg, "list") == 0) {
                        printf("list of available background modules:\n");
                        for (i = alock_backgrounds; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for (i = alock_backgrounds; *i; ++i) {
                        if (strstr(optarg, (*i)->name) == optarg) {
                            background_args = optarg;
                            opts.background = *i;
                            break;
                        }
                    }

                    if (*i == NULL) {
                        fprintf(stderr, "alock: background module not found\n");
                        exit(EXIT_FAILURE);
                    }

                }
                else {
                    fprintf(stderr, "alock: option requires an argument -- '%s'\n", "bg");
                    exit(EXIT_FAILURE);
                }
            }
            else if (!strcmp(argv[arg], "-auth")) {
                optarg = argv[++arg];
                if (optarg != NULL) {

                    struct aAuth **i;
                    if (strcmp(optarg, "list") == 0) {
                        printf("list of available authentication modules:\n");
                        for (i = alock_authmodules; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for (i = alock_authmodules; *i; ++i) {
                        if (strstr(optarg, (*i)->name) == optarg) {
                            auth_args = optarg;
                            opts.auth = *i;
                            break;
                        }
                    }

                    if (*i == NULL) {
                        fprintf(stderr, "alock: authentication module not found\n");
                        exit(EXIT_FAILURE);
                    }

                }
                else {
                    fprintf(stderr, "alock: option requires an argument -- '%s'\n", "auth");
                    exit(EXIT_FAILURE);
                }
            }
            else if (!strcmp(argv[arg], "-cursor")) {
                optarg = argv[++arg];
                if (optarg != NULL) {

                    struct aCursor **i;
                    if (strcmp(argv[arg], "list") == 0) {
                        printf("list of available cursor modules:\n");
                        for (i = alock_cursors; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for (i = alock_cursors; *i; ++i) {
                        if (strstr(optarg, (*i)->name) == optarg) {
                            cursor_args = optarg;
                            opts.cursor = *i;
                            break;
                        }
                    }

                    if (*i == NULL) {
                        fprintf(stderr, "alock: cursor module not found\n");
                        exit(EXIT_FAILURE);
                    }

                }
                else {
                    fprintf(stderr, "alock: option requires an argument -- '%s'\n", "cursor");
                    exit(EXIT_FAILURE);
                }
            }
            else if (!strcmp(argv[arg], "-input")) {
                optarg = argv[++arg];
                if (optarg != NULL) {

                    struct aInput **i;
                    if (strcmp(argv[arg], "list") == 0) {
                        printf("list of available input modules:\n");
                        for (i = alock_inputs; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for (i = alock_inputs; *i; ++i) {
                        if (strstr(optarg, (*i)->name) == optarg) {
                            input_args = optarg;
                            opts.input = *i;
                            break;
                        }
                    }

                    if (*i == NULL) {
                        fprintf(stderr, "alock: input module not found\n");
                        exit(EXIT_FAILURE);
                    }

                }
                else {
                    fprintf(stderr, "alock: option requires an argument -- '%s'\n", "input");
                    exit(EXIT_FAILURE);
                }
            }
            else if (strcmp(argv[arg], "-h") == 0) {
                printf("alock [-h] [-auth type:options] [-bg type:options]"
                       " [-cursor type:options] [-input type:options]\n");
                exit(EXIT_SUCCESS);
            }
            else {
                fprintf(stderr, "alock: invalid option '%s'\n", argv[arg]);
                exit(EXIT_FAILURE);
            }
        }
    }

    /* required for correct input handling */
    setlocale(LC_ALL, "");

    initXInfo(&xinfo);
    if (detectOtherInstance(&xinfo)) {
        fprintf(stderr, "alock: another instance seems to be running\n");
        exit(EXIT_FAILURE);
    }

    if (opts.auth->init(auth_args) == 0) {
        fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                opts.auth->name, auth_args);
        exit(EXIT_FAILURE);
    }

    /* We can be installed setuid root to support shadow passwords,
       and we don't need root privileges any longer.  --marekm */
    setuid(getuid());

    if (opts.input->init(input_args, &xinfo) == 0) {
        fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                opts.input->name, input_args);
        exit(EXIT_FAILURE);
    }
    if (opts.background->init(background_args, &xinfo) == 0) {
        fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                opts.background->name, background_args);
        exit(EXIT_FAILURE);
    }
    if (opts.cursor->init(cursor_args, &xinfo) == 0) {
        fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                opts.cursor->name, cursor_args);
        exit(EXIT_FAILURE);
    }

    {
        int scr;
        for (scr = 0; scr < xinfo.screens; scr++) {

            XSelectInput(xinfo.display, xinfo.window[scr], KeyPressMask|KeyReleaseMask);
            XMapWindow(xinfo.display, xinfo.window[scr]);
            XRaiseWindow(xinfo.display, xinfo.window[scr]);

        }
    }

    /* try to grab 2 times, another process (windowmanager) may have grabbed
     * the keyboard already */
    if ((XGrabKeyboard(xinfo.display, xinfo.window[0], True, GrabModeAsync, GrabModeAsync,
                          CurrentTime)) != GrabSuccess) {
        sleep(1);
        if ((XGrabKeyboard(xinfo.display, xinfo.window[0], True, GrabModeAsync, GrabModeAsync,
                        CurrentTime)) != GrabSuccess) {
            printf("alock: couldnt grab the keyboard\n");
            exit(EXIT_FAILURE);
        }
    }

#if HAVE_X11_EXTENSIONS_XF86MISC_H
    {
        if (XF86MiscQueryVersion(xinfo.display, &xf86misc_major, &xf86misc_minor) == True) {

            if (xf86misc_major >= 0 &&
                xf86misc_minor >= 5 &&
                XF86MiscSetGrabKeysState(xinfo.display, False) == MiscExtGrabStateLocked) {

                fprintf(stderr, "alock: cant disable xserver hotkeys to remove grabs\n");
                exit(EXIT_FAILURE);
            }

            printf("disabled AllowDeactivateGrabs and AllowClosedownGrabs\n");
        }
    }
#endif

    /* TODO: think about it: do we really need NR_SCREEN cursors ? we grab the
     * pointer on :*.0 anyway ... */
    if (XGrabPointer(xinfo.display, xinfo.window[0], False, None,
                     GrabModeAsync, GrabModeAsync, None, xinfo.cursor[0], CurrentTime) != GrabSuccess) {
        XUngrabKeyboard(xinfo.display, CurrentTime);
        fprintf(stderr, "alock: couldnt grab the pointer\n");
        exit(EXIT_FAILURE);
    }

    registerInstance(&xinfo);
    eventLoop(&opts, &xinfo);
    unregisterInstance(&xinfo);

    opts.auth->deinit();
    opts.input->deinit(&xinfo);
    opts.cursor->deinit(&xinfo);
    opts.background->deinit(&xinfo);

#if HAVE_X11_EXTENSIONS_XF86MISC_H
    if (xf86misc_major >= 0 && xf86misc_minor >= 5) {
        XF86MiscSetGrabKeysState(xinfo.display, True);
        XFlush(xinfo.display);
    }
#endif

    XCloseDisplay(xinfo.display);

    return EXIT_SUCCESS;
}
Exemple #2
0
//========================================
// main...
//----------------------------------------
int main (int argc, char*argv[]) {
	XF86MiscMouseSettings mseinfo;
	Display* dpy;
	int    c;
	int    DEBUG   = False;
	int    show    = False;
	int    Version = False;
	int    apply   = False;
	int    enable  = False;
	int    disable = False;
	int    major   = 0;
	int    minor   = 0;
	char   link    [256] = "";
	char   mydisp  [256] = "";
	char   option  [256] = "";
	char   left    [256] = "";
	struct mouse   *pointer;
	struct devnode *dev;
	struct stat    *linkstatus = NULL;

	pointer = (struct mouse*)   malloc(sizeof(struct mouse));
	dev     = (struct devnode*) malloc(sizeof(struct devnode));

	// get commandline options...
	//-----------------------------
	while (1) {
	int option_index = 0;
	static struct option long_options[] =
	{
		{"show"     , 0 , 0 , 's'},
		{"apply"    , 1 , 0 , 'a'},
		{"display"  , 1 , 0 , 'd'},
		{"help"     , 0 , 0 , 'h'},
		{"link"     , 1 , 0 , 'l'},
		{"enable"   , 0 , 0 , 'E'},
		{"disable"  , 0 , 0 , 'D'},
		{"version"  , 0 , 0 , 'v'},
		{"config"   , 0 , 0 , 'c'},
		{0          , 0 , 0 , 0  }
	};

	c = getopt_long (argc, argv, "hsa:d:l:EDvc",long_options, &option_index);
	if (c == -1)
	break;

	switch (c) {
	case 0:
		if (DEBUG) {
			fprintf (stderr,"option %s", long_options[option_index].name);
		if (optarg)
			fprintf (stderr," with arg %s", optarg);
			fprintf (stderr,"\n");
		}
	break;

	case 'h':
		usage();
	break;

	case 'c':
		showConfig();
	break;	

	case 's':
		show  = True;
	break;

	case 'v':
		Version = True;
	break;

	case 'a':
		if (! IsRoot()) {
			fprintf(stderr,"xmset: only root can do this\n");
			exit(1);
		}
		apply = True;
		strcpy(option,optarg);
	break;

    case 'l':
		// no longer used because we will get the
		// the device name (which may be a link) from the X-Server 
		// and check if it is realy a link to the pointer device. 
		// If not, no symlink is created after apply 
		// ---
		// strcpy(link,optarg);
	break;

	case 'd':
		strcpy(mydisp,optarg);
	break;

	case 'E':
		if (! IsRoot()) {
			fprintf(stderr,"xmset: only root can do this\n");
			exit(1);
		}
		enable  = True;
	break;

	case 'D':
		if (! IsRoot()) {
			fprintf(stderr,"xmset: only root can do this\n");
			exit(1);
		}
		disable = True;
		break;

	default:
		exit(1);
	}
	}
	// ...
	// open display...
	// ---
	if (strcmp(mydisp,"") == 0) {
		strcpy(mydisp,"null");
	}
	dpy = XOpen(mydisp);
	if (dpy == NULL) {
	if (Version) {
		printf("0:6\n");
	} else {
		fprintf(stderr,"xmset: could not open display\n");
	}
	exit(1);
	}
	if (Version) {
	if (XF86MiscQueryVersion(dpy,&major,&minor)) {
		printf("%d:%d\n",major,minor);
		exit (0);
	}
	}
	// ...
	// store link name if the device specification
	// of the current configuration is a link
	// ---
	if (!XF86MiscGetMouseSettings(dpy, &mseinfo)) {
		fprintf(stderr,"xmset: could not get mouse settings\n");
		exit(1);
	}
	if (apply == True) {
		linkstatus = (struct stat*)malloc(sizeof(struct stat));
		lstat (mseinfo.device,linkstatus);
		if (S_ISLNK (linkstatus->st_mode)) {
			strcpy (link,mseinfo.device);
		}
	}

	//=================================
	// enable mouse
	//---------------------------------
	if (enable == True)  {
		XF86MiscMouseSettings mseinfo;
		if (!XF86MiscGetMouseSettings(dpy, &mseinfo)) {
			exit(1);
		}
		mseinfo.flags |= MF_REOPEN;
		XSetErrorHandler (catchErrors);
		XF86MiscSetMouseSettings(dpy, &mseinfo);
		XSync(dpy, False);
		exit(0);
	}

	//=================================
	// disable mouse
	//---------------------------------
	if (disable == True) {
		XF86MiscMouseSettings mseinfo;
		if (!XF86MiscGetMouseSettings(dpy, &mseinfo)) {
			exit(1);
		}
		mseinfo.flags |= MF_REOPEN;
		mseinfo.device = "/dev/unused";
		XSetErrorHandler (catchErrors);
		XF86MiscSetMouseSettings(dpy, &mseinfo);
		XSync(dpy, False);
		exit(0);
	}

 
	//==================================
	// apply mouse settings
	//----------------------------------
	if (apply == True) {
		XF86MiscMouseSettings mseinfo;
		strsplit (option,':',left,option);  
		strcpy (pointer->device,left);
		strsplit (option,':',left,option);
		strcpy (pointer->type,left);
		strsplit (option,':',left,option);
		pointer->baudrate = atoi(left);
		strsplit (option,':',left,option);
		pointer->samplerate = atoi(left);
		strsplit (option,':',left,option);
		pointer->resolution = atoi(left);
		strsplit (option,':',left,option);
		pointer->buttons = atoi(left);
		strsplit (option,':',left,option);
		if (strcmp(left,"on") == 0) {
			strcpy(pointer->emu3button,"on");
		} else {
			strcpy(pointer->emu3button,"off");
		}
		strsplit(option,':',left,option);
		pointer->emu3timeout = atoi(left);
		strsplit(option,':',left,option);
		if (strcmp(left,"on") == 0) {
			strcpy(pointer->chordmiddle,"on");
		} else {
			strcpy(pointer->chordmiddle,"off");
		}
		strsplit (option,':',left,option);
		strcpy (pointer->flag,left);
		// ...
		// relink the /dev/sax link if the configuration
		// use a device link to point to the input device
		// ---
		if (S_ISLNK (linkstatus->st_mode)) {
			remove (link);
			symlink (pointer->device,link);
		}
		// ...
		// remove mouse from currently 
		// accessed device
		// ---
		if (!XF86MiscGetMouseSettings(dpy, &mseinfo)) {
			exit(1);
		}
		mseinfo.flags |= MF_REOPEN;
		sprintf(mseinfo.device,"disabled");
		XSetErrorHandler (catchErrors);
		XF86MiscSetMouseSettings(dpy, &mseinfo);
		XSync(dpy, False);
		// ...
		// set new mouse parameters...
		// ---
		usleep (1000);
		SetMouse (dpy,pointer);
	}

	//==================================
	// show current mouse settings
	//----------------------------------
	if (show == True) {
		GetMouse(dpy);
	}
	return(0);
}
Exemple #3
0
int main(int argc, char **argv) {


    struct aXInfo xinfo;
    struct aOpts opts;

#if HAVE_XF86MISC
    int xf86misc_major = -1;
    int xf86misc_minor = -1;
#endif

    int arg = 0;
    const char* cursor_args = NULL;
    const char* background_args = NULL;

    opts.auth = NULL;
    opts.cursor = alock_cursors[0];
    opts.background = alock_backgrounds[0];

    /*  parse options */
    if (argc != 1) {
        for(arg = 1; arg <= argc; arg++) {
            if (!strcmp(argv[arg - 1], "-bg")) {
                if (arg < argc) {

                    char* char_tmp;
                    struct aBackground* bg_tmp = NULL;
                    struct aBackground** i;
                    if (strcmp(argv[arg], "list") == 0) {
                        for(i = alock_backgrounds; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for(i = alock_backgrounds; *i; ++i) {
                        char_tmp = strstr(argv[arg], (*i)->name);
                        if(char_tmp && char_tmp == argv[arg]) {
                            background_args = char_tmp;
                            bg_tmp = *i;
                            opts.background = bg_tmp;
                            ++arg;
                            break;
                        }
                    }

                    if (bg_tmp == NULL) {
                        printf("%s", "alock: error, couldnt find the bg-module you specified.\n");
                        exit(EXIT_FAILURE);
                    }

                } else {
                    printf("%s", "alock, error, missing argument\n");
                    displayUsage();
                    exit(EXIT_FAILURE);
                }
            } else if (!strcmp(argv[arg - 1], "-auth")) {
                if (arg < argc) {

                    char* char_tmp;
                    struct aAuth* auth_tmp = NULL;
                    struct aAuth** i;
                    if (!strcmp(argv[arg], "list")) {
                        for(i = alock_authmodules; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for(i = alock_authmodules; *i; ++i) {
                        char_tmp = strstr(argv[arg], (*i)->name);
                        if(char_tmp && char_tmp == argv[arg]) {
                            auth_tmp = (*i);
                            if (auth_tmp->init(argv[arg]) == 0) {
                                printf("alock: error, failed init of [%s].\n", auth_tmp->name);
                                exit(EXIT_FAILURE);
                            }
                            opts.auth = auth_tmp;
                            ++arg;
                            break;
                        }
                    }

                    if (auth_tmp == NULL) {
                        printf("%s", "alock: error, couldnt find the auth-module you specified.\n");
                        exit(EXIT_FAILURE);
                    }

                } else {
                    printf("%s", "alock, error, missing argument\n");
                    displayUsage();
                    exit(EXIT_FAILURE);
                }
            } else if (strcmp(argv[arg - 1], "-cursor") == 0) {
                if (arg < argc) {

                    char* char_tmp;
                    struct aCursor* cursor_tmp = NULL;
                    struct aCursor** i;
                    if (strcmp(argv[arg], "list") == 0) {
                        for(i = alock_cursors; *i; ++i) {
                            printf("%s\n", (*i)->name);
                        }
                        exit(EXIT_SUCCESS);
                    }

                    for(i = alock_cursors; *i; ++i) {
                        char_tmp = strstr(argv[arg], (*i)->name);
                        if(char_tmp && char_tmp == argv[arg]) {
                            cursor_args = char_tmp;
                            cursor_tmp = *i;
                            opts.cursor= cursor_tmp;
                            ++arg;
                            break;
                        }
                    }

                    if (!cursor_tmp) {
                        printf("%s", "alock: error, couldnt find the cursor-module you specified.\n");
                        exit(EXIT_FAILURE);
                    }

                } else {
                    printf("%s", "alock, error, missing argument\n");
                    displayUsage();
                    exit(EXIT_FAILURE);
                }
            } else if (strcmp(argv[arg - 1], "-h") == 0) {
                displayUsage();
                exit(EXIT_SUCCESS);
            } else if (strcmp(argv[arg - 1], "-v") == 0) {
                printf("alock-%s by m.gumz 2005 - 2006\n", VERSION);
                exit(EXIT_SUCCESS);
            }
        }
    }


    initStartTime();
    initXInfo(&xinfo);
    if (detectOtherInstance(&xinfo)) {
        printf("%s", "alock: error, another instance seems to be running\n");
        exit(EXIT_FAILURE);
    }

    if (!opts.auth) {
        printf("%s", "alock: error, no auth-method specified.\n");
        displayUsage();
        exit(EXIT_FAILURE);
    }

    if (opts.background->init(background_args, &xinfo) == 0) {
        printf("alock: error, couldnt init [%s] with [%s].\n",
               opts.background->name,
               background_args);
        exit(EXIT_FAILURE);
    }

    if (opts.cursor->init(cursor_args, &xinfo) == 0) {
        printf("alock: error, couldnt init [%s] with [%s].\n",
               opts.cursor->name,
               cursor_args);
        exit(EXIT_FAILURE);
    }

    {
        int scr;
        for (scr = 0; scr < xinfo.nr_screens; scr++) {

            XSelectInput(xinfo.display, xinfo.window[scr], KeyPressMask|KeyReleaseMask);
            XMapWindow(xinfo.display, xinfo.window[scr]);
            XRaiseWindow(xinfo.display, xinfo.window[scr]);

        }
    }

    /* try to grab 2 times, another process (windowmanager) may have grabbed
     * the keyboard already */
    if ((XGrabKeyboard(xinfo.display, xinfo.window[0], True, GrabModeAsync, GrabModeAsync,
                          CurrentTime)) != GrabSuccess) {
        sleep(1);
        if ((XGrabKeyboard(xinfo.display, xinfo.window[0], True, GrabModeAsync, GrabModeAsync,
                        CurrentTime)) != GrabSuccess) {
            printf("%s", "alock: couldnt grab the keyboard.\n");
            exit(EXIT_FAILURE);
        }
    }

#if HAVE_XF86MISC
    {
        if (XF86MiscQueryVersion(xinfo.display, &xf86misc_major, &xf86misc_minor) == True) {

            if (xf86misc_major >= 0 &&
                xf86misc_minor >= 5 &&
                XF86MiscSetGrabKeysState(xinfo.display, False) == MiscExtGrabStateLocked) {

                printf("%s", "alock: cant disable xserver hotkeys to remove grabs.\n");
                exit(EXIT_FAILURE);
            }

            printf("%s", "disabled AllowDeactivateGrabs and AllowClosedownGrabs\n.");
        }
    }
#endif

    /* TODO: think about it: do we really need NR_SCREEN cursors ? we grab the
     * pointer on :*.0 anyway ... */
    if (XGrabPointer(xinfo.display, xinfo.window[0], False, None,
                     GrabModeAsync, GrabModeAsync, None, xinfo.cursor[0], CurrentTime) != GrabSuccess) {
        XUngrabKeyboard(xinfo.display, CurrentTime);
        printf("%s", "alock: couldnt grab the pointer.\n");
        exit(EXIT_FAILURE);
    }

    registerInstance(&xinfo);
    eventLoop(&opts, &xinfo);
    unregisterInstance(&xinfo);

    opts.auth->deinit();
    opts.cursor->deinit(&xinfo);
    opts.background->deinit(&xinfo);

#if HAVE_XF86MISC
    if (xf86misc_major >= 0 && xf86misc_minor >= 5) {
        XF86MiscSetGrabKeysState(xinfo.display, True);
        XFlush(xinfo.display);
    }
#endif

    XCloseDisplay(xinfo.display);

    return EXIT_SUCCESS;
}
Exemple #4
0
int main(int argc, char **argv) {

    int opt;
    struct option longopts[] = {
        {"help", no_argument, NULL, 'h'},
        {"modules", no_argument, NULL, 'm'},
        {"auth", required_argument, NULL, 'a'},
        {"bg", required_argument, NULL, 'b'},
        {"cursor", required_argument, NULL, 'c'},
        {"input", required_argument, NULL, 'i'},
        {0, 0, 0, 0},
    };

    Display *display;
    struct aModules modules;
    int retval;

    const char *args_auth = NULL;
    const char *args_background = NULL;
    const char *args_cursor = NULL;
    const char *args_input = NULL;

    /* set-up default modules */
    modules.auth = alock_modules_auth[0];
    modules.background = alock_modules_background[0];
    modules.cursor = alock_modules_cursor[0];
    modules.input = alock_modules_input[0];

#if WITH_XBLIGHT
    modules.backlight = -1;
#endif

    /* parse options */
    while ((opt = getopt_long_only(argc, argv, "hma:b:c:i:", longopts, NULL)) != -1)
        switch (opt) {
        case 'h':
            printf("%s [-help] [-modules] [-auth type:options] [-bg type:options]"
                    " [-cursor type:options] [-input type:options]\n", argv[0]);
            return EXIT_SUCCESS;

        case 'm': { /* list available modules */

            struct aModuleAuth **ia;
            struct aModuleBackground **ib;
            struct aModuleCursor **ic;
            struct aModuleInput **ii;

            printf("authentication modules:\n");
            for (ia = alock_modules_auth; *ia; ++ia)
                printf("  %s\n", (*ia)->m.name);

            printf("background modules:\n");
            for (ib = alock_modules_background; *ib; ++ib)
                printf("  %s\n", (*ib)->m.name);

            printf("cursor modules:\n");
            for (ic = alock_modules_cursor; *ic; ++ic)
                printf("  %s\n", (*ic)->m.name);

            printf("input modules:\n");
            for (ii = alock_modules_input; *ii; ++ii)
                printf("  %s\n", (*ii)->m.name);

            return EXIT_SUCCESS;
        }

        case 'a': { /* authentication module */

            struct aModuleAuth **i;
            for (i = alock_modules_auth; *i; ++i)
                if (strstr(optarg, (*i)->m.name) == optarg) {
                    args_auth = optarg;
                    modules.auth = *i;
                    break;
                }

            if (*i == NULL) {
                fprintf(stderr, "alock: authentication module `%s` not found\n", optarg);
                return EXIT_FAILURE;
            }

            break;
        }

        case 'b': { /* background module */

            struct aModuleBackground **i;
            for (i = alock_modules_background; *i; ++i)
                if (strstr(optarg, (*i)->m.name) == optarg) {
                    args_background = optarg;
                    modules.background = *i;
                    break;
                }

            if (*i == NULL) {
                fprintf(stderr, "alock: background module `%s` not found\n", optarg);
                return EXIT_FAILURE;
            }

            break;
        }

        case 'c': { /* cursor module */

            struct aModuleCursor **i;
            for (i = alock_modules_cursor; *i; ++i)
                if (strstr(optarg, (*i)->m.name) == optarg) {
                    args_cursor = optarg;
                    modules.cursor = *i;
                    break;
                }

            if (*i == NULL) {
                fprintf(stderr, "alock: cursor module `%s` not found\n", optarg);
                return EXIT_FAILURE;
            }

            break;
        }

        case 'i': { /* input module */

            struct aModuleInput **i;
            for (i = alock_modules_input; *i; ++i)
                if (strstr(optarg, (*i)->m.name) == optarg) {
                    args_input = optarg;
                    modules.input = *i;
                    break;
                }

            if (*i == NULL) {
                fprintf(stderr, "alock: input module `%s` not found\n", optarg);
                return EXIT_FAILURE;
            }

            break;
        }

        default:
            fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
            return EXIT_FAILURE;
        }

    /* required for correct input handling */
    setlocale(LC_ALL, "");

    if ((display = XOpenDisplay(NULL)) == NULL) {
        fprintf(stderr, "error: unable to connect to the X display\n");
        return EXIT_FAILURE;
    }

    /* make sure, that only one instance of alock is running */
    if (registerInstance(display)) {
        fprintf(stderr, "error: another instance seems to be running\n");
        XCloseDisplay(display);
        return EXIT_FAILURE;
    }

#if WITH_DUNST
    /* pause notification daemon */
    system("pkill -x -SIGUSR1 dunst");
#endif

    { /* try to initialize selected modules */

        int rv = 0;

        XrmInitialize();
        const char *data = XResourceManagerString(display);
        XrmDatabase xrdb = XrmGetStringDatabase(data != NULL ? data : "");

        modules.auth->m.loadxrdb(xrdb);
        modules.background->m.loadxrdb(xrdb);
        modules.cursor->m.loadxrdb(xrdb);
        modules.input->m.loadxrdb(xrdb);

#if WITH_XBLIGHT
        XrmValue value;
        char *type;

        if (XrmGetResource(xrdb, "alock.backlight", "ALock.Backlight",
                    &type, &value) && strcmp(value.addr, "true") == 0)
            modules.backlight = getBacklightBrightness();
#endif /* WITH_XBLIGHT */

        XrmDestroyDatabase(xrdb);

        modules.auth->m.loadargs(args_auth);
        modules.background->m.loadargs(args_background);
        modules.cursor->m.loadargs(args_cursor);
        modules.input->m.loadargs(args_input);

        if (modules.auth->m.init(display)) {
            fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                    modules.auth->m.name, args_auth);
            rv |= 1;
        }

#if ENABLE_PASSWD
        /* We can be installed setuid root to support shadow passwords,
         * and we don't need root privileges any longer.  --marekm */
        if (setuid(getuid()) != 0)
            perror("alock: root privilege drop failed");
#endif

        if (modules.background->m.init(display)) {
            fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                    modules.background->m.name, args_background);
            rv |= 1;
        }
        if (modules.cursor->m.init(display)) {
            fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                    modules.cursor->m.name, args_cursor);
            rv |= 1;
        }
        if (modules.input->m.init(display)) {
            fprintf(stderr, "alock: failed init of [%s] with [%s]\n",
                    modules.input->m.name, args_input);
            rv |= 1;
        }

        if (rv) /* initialization failed */
            goto return_failure;

    }

#if HAVE_XMISC
    int xf86misc_major = -1;
    int xf86misc_minor = -1;

    if (XF86MiscQueryVersion(display, &xf86misc_major, &xf86misc_minor) == True) {

        if (xf86misc_major >= 0 && xf86misc_minor >= 5 &&
                XF86MiscSetGrabKeysState(display, False) == MiscExtGrabStateLocked) {

            fprintf(stderr, "error: unable to disable Xorg hotkeys to remove grabs\n");
            goto return_failure;
        }

        fprintf(stderr, "info: disabled AllowDeactivateGrabs and AllowClosedownGrabs\n");
    }
#endif /* HAVE_XMISC */

    /* raise our background window and grab input, if this action has failed,
     * we are not able to lock the screen, then we're f****d... */
    if (lockDisplay(display, &modules))
        goto return_failure;

    debug("entering main event loop");
    eventLoop(display, &modules);

    retval = EXIT_SUCCESS;
    goto return_success;

return_failure:
    retval = EXIT_FAILURE;

return_success:

#if HAVE_XMISC
    if (xf86misc_major >= 0 && xf86misc_minor >= 5) {
        XF86MiscSetGrabKeysState(display, True);
        XFlush(display);
    }
#endif

    modules.auth->m.free();
    modules.cursor->m.free();
    modules.input->m.free();
    modules.background->m.free();

    unregisterInstance(display);
    XCloseDisplay(display);

#if WITH_DUNST
    /* resume notification daemon */
    system("pkill -x -SIGUSR2 dunst");
#endif

    return retval;
}