/* * lockscreen2.c * Copyright (C) 2006,2007,2008 mariodebian at gmail * Copyright (C) 2008 vidal_joshur at gva.es * * This file is based on screen-locker of iTALC project: * screen_locker.c - screen-locker, which is part of the iTALC client-software * * iTALC/Client-software * Copyright (c) 2004-2005 Tobias Doerffel * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include "X11/extensions/shape.h" #include #ifndef LOCKSCREEN_IMAGE #define LOCKSCREEN_IMAGE "/usr/share/tcos-core/lockscreen-custom.png" #endif #ifndef LOCKSCREEN_IMAGE_TCOS #define LOCKSCREEN_IMAGE_TCOS "/usr/share/tcos-core/lockscreen.png" #endif int setenv(const char *name, const char *value, int overwrite); #include int file_exists (char * fileName) { struct stat buf; int i = stat ( fileName, &buf ); /* File found */ if ( i == 0 ) return 1; return 0; } #define AllPointerEventMask \ (ButtonPressMask | ButtonReleaseMask | \ EnterWindowMask | LeaveWindowMask | \ PointerMotionMask | PointerMotionHintMask | \ Button1MotionMask | Button2MotionMask | \ Button3MotionMask | Button4MotionMask | \ Button5MotionMask | ButtonMotionMask | \ KeymapStateMask) int main (int argc, char **argv) { XtResource desktopBackingStoreResources[] = { { XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0, XtRImmediate, (XtPointer) Always, }, }; Display * display; /*Visual * vis;*/ XSetWindowAttributes attr; unsigned long valuemask; int count = 0; Pixmap src, msk; XColor fg, bg; int blackColor; GC gc; Widget toplevel; Dimension displayWidth, displayHeight; Cursor blankcursor; Widget form, viewport, desktop; Window desktop_win; char srcBits[] = { 0,0,0,0,0 }; char mskBits[] = { 0,0,0,0,0 }; Imlib_Image *image; Pixmap pixmap, mask; int image_x, image_y, rc; int screen, depth; setenv("XLIB_SKIP_ARGB_VISUALS", "1", 1); /* Call the main Xt initialisation function. It parses command-line options, generating appropriate resource specs, and makes a * connection to the X display. */ toplevel = XtVaAppInitialize(NULL, "ScreenLocker", NULL, 0, &argc, argv, NULL, XtNborderWidth, 0, NULL); display = XtDisplay(toplevel); (void)DefaultVisual(display, DefaultScreen(display)); displayWidth = WidthOfScreen(DefaultScreenOfDisplay(display)); displayHeight = HeightOfScreen(DefaultScreenOfDisplay(display)); screen = DefaultScreen(display); depth = DefaultDepth(display, screen); /* full screen - set position to 0,0, but defer size calculation until widgets are realized */ XtVaSetValues(toplevel, XtNoverrideRedirect, True, XtNgeometry, "+0+0", NULL); form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, XtNborderWidth, 0, XtNdefaultDistance, 0, NULL); viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, XtNborderWidth, 0, NULL); desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport, XtNborderWidth, 0, NULL); XtVaSetValues(desktop, XtNwidth, displayWidth, XtNheight, displayHeight, NULL); /* "Realize" all the widgets, i.e. actually create and map their X windows */ XtRealizeWidget(toplevel); /* We want to stop the window manager from managing our toplevel window. This is not really a nice thing to do, so may not work * properly with every window manager. We do this simply by setting overrideRedirect and reparenting our window to the root. * The window manager will get a ReparentNotify and hopefully clean up its frame window. */ XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL); XReparentWindow(display, XtWindow(toplevel), DefaultRootWindow(display), 0, 0); /* Now we want to fix the size of "viewport". We shouldn't just change it directly. * Instead we set "toplevel" to the required size (which should propagate through "form" to "viewport"). * Then we remove "viewport" from being managed by "form", change its resources to position it and make sure that "form" won't * attempt to resize it, then ask "form" to manage it again. */ XtResizeWidget(toplevel, displayWidth, displayHeight, 0); XtUnmanageChild(viewport); XtVaSetValues(viewport, XtNhorizDistance, 0, XtNvertDistance, 0, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); XtManageChild(viewport); /* Now we can set "toplevel" to its proper size. */ XtResizeWidget(toplevel, displayWidth, displayHeight, 0); /*image = XCreateImage(display, vis, 32, ZPixmap, 0, NULL, 2000, 2000, BitmapPad(display), 0);*/ blackColor = BlackPixel(display, DefaultScreen(display)); desktop_win = XtWindow(desktop); gc = XCreateGC(display, desktop_win, 0, NULL); if ( file_exists (LOCKSCREEN_IMAGE) || file_exists(LOCKSCREEN_IMAGE_TCOS) ) { imlib_context_set_display(display); imlib_context_set_visual(DefaultVisual(display, DefaultScreen(display))); imlib_context_set_colormap(DefaultColormap(display, DefaultScreen(display))); imlib_set_color_usage(128); imlib_context_set_dither(1); if ( file_exists(LOCKSCREEN_IMAGE) ) { printf("loading custom image %s...\n", LOCKSCREEN_IMAGE); image=imlib_load_image(LOCKSCREEN_IMAGE); } else { printf("loading TCOS image %s...\n", LOCKSCREEN_IMAGE_TCOS); image=imlib_load_image(LOCKSCREEN_IMAGE_TCOS); } imlib_context_set_image(image); image_x = imlib_image_get_width(); image_y = imlib_image_get_height(); printf("image x=%d y=%d displayWidth=%d displayHeight=%d\n", image_x, image_y, displayWidth, displayHeight); pixmap = XCreatePixmap(display, desktop_win, displayWidth, displayHeight, depth); imlib_context_set_drawable(desktop_win); imlib_render_image_on_drawable_at_size(0, 0, displayWidth, displayHeight); imlib_render_pixmaps_for_whole_image_at_size(&pixmap, &mask, displayWidth, displayHeight); rc = XSetWindowBackgroundPixmap(display, desktop_win, pixmap ); switch (rc) { case BadMatch: fprintf(stderr, "XSetWindowBackgroundPixmap - BadMatch.\n"); exit(1); break; case BadPixmap: fprintf(stderr, "XSetWindowBackgroundPixmap - BadPixmap.\n"); exit(1); break; case BadWindow: fprintf(stderr, "XSetWindowBackgroundPixmap - BadWindow.\n"); exit(1); break; } if (mask) { XShapeCombineMask(display, desktop_win, ShapeBounding, 0, 0, mask, ShapeSet); } XMapWindow(display, desktop_win); XSetForeground(display, gc, blackColor); XFillRectangle( display, pixmap, gc, 0, 0, displayWidth, displayHeight ); if (image) imlib_free_image(); if(pixmap) XFreePixmap(display, pixmap); if(pixmap) imlib_free_pixmap_and_mask(pixmap); pixmap = None; if(gc) XFreeGC(display, gc); } else { /* Tell the GC we draw using the black color*/ printf("file %s not exists!!\n", LOCKSCREEN_IMAGE); XSetForeground(display, gc, blackColor); XFillRectangle(display, desktop_win, gc, 0, 0, displayWidth, displayHeight); } src = XCreateBitmapFromData(display, DefaultRootWindow(display), srcBits, 5, 5); msk = XCreateBitmapFromData(display, DefaultRootWindow(display), mskBits, 5, 5); XAllocNamedColor(display, DefaultColormap(display,DefaultScreen(display)), "black", &fg, &fg); XAllocNamedColor(display, DefaultColormap(display,DefaultScreen(display)), "white", &bg, &bg); blankcursor = XCreatePixmapCursor(display, src, msk, &fg, &bg, 2, 2); XFreePixmap(display, src); XFreePixmap(display, msk); XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store, desktopBackingStoreResources, 1, NULL); valuemask = CWBackingStore; attr.cursor = blankcursor; valuemask |= CWCursor; XChangeWindowAttributes(display, desktop_win, valuemask, &attr); /* Try to get the input focus. */ XSetInputFocus(display, DefaultRootWindow(display), RevertToPointerRoot, CurrentTime); /* Try to dont allow screensaver to activate */ XForceScreenSaver(display, (int) ScreenSaverReset); while (count < 5) { if (XSetScreenSaver(display, 0, 0, (int) DontPreferBlanking, (int) DontAllowExposures) != BadValue ) { break; } printf ("lockscreen::screensaver Could not disable screensaver, Badvalue=%d Count=%d.\n", BadValue, count); sleep (1); count++; } XUngrabKeyboard(display, CurrentTime); XUngrabPointer(display, CurrentTime); count=0; /* now grab keyboard and mouse */ while (count < 5) { if (XtGrabKeyboard(toplevel, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess || XtGrabPointer(toplevel, True, (unsigned int) AllPointerEventMask, GrabModeAsync, GrabModeAsync, None, blankcursor, CurrentTime) != GrabSuccess) { printf ("lockscreen::keybmouse Could not grab keyboard and mouse, Count=%d.\n", count); sleep (1); count++; } else { break; } } #ifndef DEBUG while (1) { /* wait in a loop */ sleep (5); } #else sleep(3); printf("DEBUG: quiting...\n"); #endif XCloseDisplay(display); return(0); }