/* * $Id$ * * Evoke, head honcho of everything * Part of Equinox Desktop Environment (EDE). * Copyright (c) 2000-2007 EDE Authors. * * This program is licensed under terms of the * GNU General Public License version 2 or newer. * See COPYING for details. */ #include "Logout.h" #include #include #include #include #include #include #include #include #include // memset static int logout_ret; static Fl_Double_Window* win; static Fl_Round_Button* rb1; static Fl_Round_Button* rb2; static Fl_Round_Button* rb3; unsigned char* take_x11_screenshot(unsigned char *p, int X, int Y, int w, int h, int alpha); unsigned char* make_darker(unsigned char *p, int X, int Y, int w, int h); void rb_cb(Fl_Widget*, void* r) { Fl_Round_Button* rb = (Fl_Round_Button*)r; if(rb == rb2) { rb1->value(0); rb3->value(0); } else if(rb == rb3) { rb1->value(0); rb2->value(0); } else { rb2->value(0); rb3->value(0); } rb->value(1); } void ok_cb(Fl_Widget*, void*) { if(rb1->value()) logout_ret = LOGOUT_LOGOUT; else if(rb2->value()) logout_ret = LOGOUT_RESTART; else logout_ret = LOGOUT_SHUTDOWN; win->hide(); } void cancel_cb(Fl_Widget*, void*) { logout_ret = LOGOUT_CANCEL; win->hide(); } int logout_dialog(int screen_w, int screen_h, bool disable_restart, bool disable_shutdown) { logout_ret = 0; unsigned char* imgdata = NULL; imgdata = take_x11_screenshot(imgdata, 0, 0, screen_w, screen_h, 0); if(imgdata) imgdata = make_darker(imgdata, 0, 0, screen_w, screen_h); //win = new Fl_Double_Window(365, 265, 325, 185, _("Logout, restart or shutdown")); win = new Fl_Double_Window(0, 0, screen_w, screen_h, _("Logout, restart or shutdown")); win->begin(); Fl_Box* bb = new Fl_Box(0, 0, win->w(), win->h()); Fl_RGB_Image* img = new Fl_RGB_Image(imgdata, 1024, 768); img->alloc_array = 1; bb->image(img); //Fl_Group* g = new Fl_Group(365, 265, 325, 185); Fl_Group* g = new Fl_Group(0, 0, 325, 185); g->box(FL_THIN_UP_BOX); g->begin(); Fl_Box* b = new Fl_Box(10, 9, 305, 39, _("Logout, restart or shut down the computer ?")); b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_WRAP); b->labelfont(FL_HELVETICA_BOLD); rb1 = new Fl_Round_Button(25, 60, 275, 20, _("Logout from the current session")); rb1->down_box(FL_ROUND_DOWN_BOX); rb1->value(1); rb1->callback(rb_cb, rb1); rb2 = new Fl_Round_Button(25, 85, 275, 20, _("Restart the computer")); rb2->down_box(FL_ROUND_DOWN_BOX); rb2->value(0); rb2->callback(rb_cb, rb2); if(disable_restart) rb2->deactivate(); rb3 = new Fl_Round_Button(25, 110, 275, 20, _("Shut down the computer")); rb3->down_box(FL_ROUND_DOWN_BOX); rb3->value(0); rb3->callback(rb_cb, rb3); if(disable_shutdown) rb3->deactivate(); Fl_Button* ok = new Fl_Button(130, 150, 90, 25, _("&OK")); ok->callback(ok_cb); Fl_Button* cancel = new Fl_Button(225, 150, 90, 25, _("&Cancel")); cancel->callback(cancel_cb); g->end(); g->position(screen_w/2 - g->w()/2, screen_h/2 - g->h()/2); win->end(); win->clear_border(); win->set_override(); win->show(); while(win->shown()) Fl::wait(); return logout_ret; } unsigned char* make_darker(unsigned char *p, int X, int Y, int w, int h) { if(!p) return 0; unsigned char* pdata = p; int step = 100; for(int j = 0; j < h; j++) { for(int i = 0; i < w; i++) { // red if(*pdata > step) *pdata -= step; pdata++; // green if(*pdata > step) *pdata -= step; pdata++; // blue if(*pdata > step) *pdata -= step; pdata++; } } return p; } // stolen from fl_read_image.cxx unsigned char* take_x11_screenshot(unsigned char *p, int X, int Y, int w, int h, int alpha) { XImage *image; int i, maxindex; int x, y; // Current X & Y in image int d; // Depth of image unsigned char *line, // Array to hold image row *line_ptr; // Pointer to current line image unsigned char *pixel; // Current color value XColor colors[4096]; // Colors from the colormap... unsigned char cvals[4096][3]; // Color values from the colormap... unsigned index_mask, index_shift, red_mask, red_shift, green_mask, green_shift, blue_mask, blue_shift; // // Under X11 we have the option of the XGetImage() interface or SGI's // ReadDisplay extension which does all of the really hard work for // us... // image = 0; if (!image) { image = XGetImage(fl_display, RootWindow(fl_display, fl_screen), X, Y, w, h, AllPlanes, ZPixmap); } if (!image) return 0; d = alpha ? 4 : 3; // Allocate the image data array as needed... if (!p) p = new unsigned char[w * h * d]; // Initialize the default colors/alpha in the whole image... memset(p, alpha, w * h * d); // Check that we have valid mask/shift values... if (!image->red_mask && image->bits_per_pixel > 12) { // Greater than 12 bits must be TrueColor... image->red_mask = fl_visual->visual->red_mask; image->green_mask = fl_visual->visual->green_mask; image->blue_mask = fl_visual->visual->blue_mask; } // Check if we have colormap image... if (!image->red_mask) { // Get the colormap entries for this window... maxindex = fl_visual->visual->map_entries; for (i = 0; i < maxindex; i ++) colors[i].pixel = i; XQueryColors(fl_display, fl_colormap, colors, maxindex); for (i = 0; i < maxindex; i ++) { cvals[i][0] = colors[i].red >> 8; cvals[i][1] = colors[i].green >> 8; cvals[i][2] = colors[i].blue >> 8; } // Read the pixels and output an RGB image... for (y = 0; y < image->height; y ++) { pixel = (unsigned char *)(image->data + y * image->bytes_per_line); line = p + y * w * d; switch (image->bits_per_pixel) { case 1 : for (x = image->width, line_ptr = line, index_mask = 128; x > 0; x --, line_ptr += d) { if (*pixel & index_mask) { line_ptr[0] = cvals[1][0]; line_ptr[1] = cvals[1][1]; line_ptr[2] = cvals[1][2]; } else { line_ptr[0] = cvals[0][0]; line_ptr[1] = cvals[0][1]; line_ptr[2] = cvals[0][2]; } if (index_mask > 1) { index_mask >>= 1; } else { index_mask = 128; pixel ++; } } break; case 2 : for (x = image->width, line_ptr = line, index_shift = 6; x > 0; x --, line_ptr += d) { i = (*pixel >> index_shift) & 3; line_ptr[0] = cvals[i][0]; line_ptr[1] = cvals[i][1]; line_ptr[2] = cvals[i][2]; if (index_shift > 0) { index_mask >>= 2; index_shift -= 2; } else { index_mask = 192; index_shift = 6; pixel ++; } } break; case 4 : for (x = image->width, line_ptr = line, index_shift = 4; x > 0; x --, line_ptr += d) { if (index_shift == 4) i = (*pixel >> 4) & 15; else i = *pixel & 15; line_ptr[0] = cvals[i][0]; line_ptr[1] = cvals[i][1]; line_ptr[2] = cvals[i][2]; if (index_shift > 0) { index_shift = 0; } else { index_shift = 4; pixel ++; } } break; case 8 : for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel ++) { line_ptr[0] = cvals[*pixel][0]; line_ptr[1] = cvals[*pixel][1]; line_ptr[2] = cvals[*pixel][2]; } break; case 12 : for (x = image->width, line_ptr = line, index_shift = 0; x > 0; x --, line_ptr += d) { if (index_shift == 0) { i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; } else { i = ((pixel[1] << 8) | pixel[2]) & 4095; } line_ptr[0] = cvals[i][0]; line_ptr[1] = cvals[i][1]; line_ptr[2] = cvals[i][2]; if (index_shift == 0) { index_shift = 4; } else { index_shift = 0; pixel += 3; } } break; } } } else { // RGB(A) image, so figure out the shifts & masks... red_mask = image->red_mask; red_shift = 0; while ((red_mask & 1) == 0) { red_mask >>= 1; red_shift ++; } green_mask = image->green_mask; green_shift = 0; while ((green_mask & 1) == 0) { green_mask >>= 1; green_shift ++; } blue_mask = image->blue_mask; blue_shift = 0; while ((blue_mask & 1) == 0) { blue_mask >>= 1; blue_shift ++; } // Read the pixels and output an RGB image... for (y = 0; y < image->height; y ++) { pixel = (unsigned char *)(image->data + y * image->bytes_per_line); line = p + y * w * d; switch (image->bits_per_pixel) { case 8 : for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel ++) { i = *pixel; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } break; case 12 : for (x = image->width, line_ptr = line, index_shift = 0; x > 0; x --, line_ptr += d) { if (index_shift == 0) { i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; } else { i = ((pixel[1] << 8) | pixel[2]) & 4095; } line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; if (index_shift == 0) { index_shift = 4; } else { index_shift = 0; pixel += 3; } } break; case 16 : if (image->byte_order == LSBFirst) { // Little-endian... for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel += 2) { i = (pixel[1] << 8) | pixel[0]; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } } else { // Big-endian... for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel += 2) { i = (pixel[0] << 8) | pixel[1]; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } } break; case 24 : if (image->byte_order == LSBFirst) { // Little-endian... for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel += 3) { i = (((pixel[2] << 8) | pixel[1]) << 8) | pixel[0]; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } } else { // Big-endian... for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel += 3) { i = (((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } } break; case 32 : if (image->byte_order == LSBFirst) { // Little-endian... for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel += 4) { i = (((((pixel[3] << 8) | pixel[2]) << 8) | pixel[1]) << 8) | pixel[0]; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } } else { // Big-endian... for (x = image->width, line_ptr = line; x > 0; x --, line_ptr += d, pixel += 4) { i = (((((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]) << 8) | pixel[3]; line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; } } break; } } } // Destroy the X image we've read and return the RGB(A) image... XDestroyImage(image); return p; }