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; }
// execution begins here int UltraMain(void) { struct display_context * dc; struct controller_data cd; int lasty=0,lastx=0; int d=0; // buffer for rendering text strings (only sprintf works at the moment) char buf[1024]; // offset for the scrolling waveform float offs=0; // used to keep track of how many cycles various processes take unsigned long time,rendertime,lastrendertime,waittime,lastwaittime; // enable MI interrupts (on the CPU) set_MI_interrupt(1); initDisplay(); initAudio(); registerAIhandler(AIcallback); registerVIhandler(VIcallback); while (1) { short * sb; int sbsize; // Mark the value of the COUNT register (increments at half the CPU // rate) at the start of the main loop. time=read_count(); while (! (dc=lockDisplay())) ; // Mark the time after waiting. waittime=time; waittime=((time=read_count())-waittime)*2; sb=getbuf(); sbsize=getbufsize(); for (int c=0;c<sbsize;c++,d++) { sb[c*2]=sin((d%22050)/22050.0*M_TWOPI*1000.0)*100*((cd.c[0].y-lasty)*c/sbsize+lasty)*(((cd.c[0].x-lastx)*c/sbsize+lastx)/128.0-1.0); sb[c*2+1]=sin((d%22050)/22050.0*M_TWOPI*1000.0)*100*((cd.c[0].y-lasty)*c/sbsize+lasty)*(((cd.c[0].x-lastx)*c/sbsize+lastx)/128.0+1.0); } writebuffer(sb); lastx=cd.c[0].x; lasty=cd.c[0].y; // this is what really marks the beginning of the current frame // read controller data controller_Read(&cd); // start drawing on the other frame buffer, clear the screen (uses red // when the start button on controller 1 is pressed, black otherwise) VI_FillScreen(&dc->conf,cd.c[0].err?0:(cd.c[0].start?0xf800:0)); // print a little info for each controller for (int c=0; c < 4; c++) { if (cd.c[c].err) // if controller not present sprintf(buf,"controller %d not present",c+1); else { sprintf(buf,"controller %d present\nbuttons=0x%04X x=%4d y=%4d",c+1, cd.c[c].buttons, cd.c[c].x, cd.c[c].y); } VI_DrawText(&dc->conf,50,58+2*8*c,buf); } // draw a waveform for (float x=50; x < 250; x++) { VI_DrawPixel(&dc->conf,x,cbrt(sin((x-50)/200*M_TWOPI*4+offs))*250.0/8+175,0x7c0); } // the waveform can be scrolled by the x axis of the first controller if (!cd.c[0].err) offs-=(cd.c[0].x/2*2)/32.0; // print up some informative text, and report how long we waited for // this frame, and how long the last frame took to render sprintf(buf,"buffers: %5d frames: %5d\n%8lu cycles last frame\n%8lu cycles waiting\n%4.2f FPS",buffercount,framecount,lastrendertime,lastwaittime,100000000.0/(lastwaittime+lastrendertime)); VI_DrawText(&dc->conf,50,26,buf); // calculate how many cycles this frame took to render rendertime=(read_count()-time)*2; lastwaittime=waittime; lastrendertime=rendertime; showDisplay(dc); dc=0; } return 0; }