Small fix in case of desktop icon without image.

Rootpmap accepts now works for 16/24 bit displays with 16/24/32 bit images.
This commit is contained in:
Sanel Zukan 2007-06-22 09:43:15 +00:00
parent d91784d0de
commit f006fb0d0f
5 changed files with 225 additions and 64 deletions

View File

@ -22,7 +22,11 @@
#include <edelib/Debug.h> #include <edelib/Debug.h>
#include <edelib/IconTheme.h> #include <edelib/IconTheme.h>
#define USE_SHAPE 1
#ifdef USE_SHAPE
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#endif
// minimal icon size // minimal icon size
#define ICONSIZE 48 #define ICONSIZE 48
@ -34,7 +38,6 @@
// label offset from icon y()+h(), so selection box can be drawn nicely // label offset from icon y()+h(), so selection box can be drawn nicely
#define LABEL_OFFSET 2 #define LABEL_OFFSET 2
#define SHAPE 1
DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) : DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) :
Fl_Widget(is->x, is->y, ICONSIZE, ICONSIZE) { Fl_Widget(is->x, is->y, ICONSIZE, ICONSIZE) {
@ -121,15 +124,42 @@ void DesktopIcon::update_label_size(void) {
void DesktopIcon::drag(int x, int y, bool apply) { void DesktopIcon::drag(int x, int y, bool apply) {
if(!micon) { if(!micon) {
micon = new MovableIcon(this); micon = new MovableIcon(this);
micon->show(); #if USE_SHAPE
/*
* This is used to calculate correct window startup/ending
* position since icon is placed in the middle of the box.
*
* Opposite, window (shaped) will have small but noticeable 'jump off' and
* dropped icon position will not be at the exact place where was dropped.
*/
int ix, iy;
ix = iy = 0;
if(image()) {
ix = (w()/2) - (image()->w()/2);
iy = (h()/2) - (image()->h()/2);
} }
micon->position(micon->x() + ix, micon->y() + iy);
#endif
micon->show();
} else {
EASSERT(micon != NULL); EASSERT(micon != NULL);
micon->position(x, y); micon->position(x, y);
}
if(apply) { if(apply) {
#if USE_SHAPE
int ix, iy;
ix = iy = 0;
if(image()) {
ix = (w()/2) - (image()->w()/2);
iy = (h()/2) - (image()->h()/2);
}
position(micon->x() - ix, micon->y() - iy);
#else
position(micon->x(), micon->y()); position(micon->x(), micon->y());
#endif
delete micon; delete micon;
micon = NULL; micon = NULL;
} }
@ -241,20 +271,23 @@ int DesktopIcon::handle(int event) {
return 1; return 1;
} }
MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) { MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic), mask(0) {
EASSERT(icon != NULL); EASSERT(icon != NULL);
set_override(); set_override();
color(ic->color()); color(ic->color());
begin(); begin();
Fl_Image* img = ic->icon_image();
/* /*
* Force box be same width/height as icon so it * Force box be same width/height as icon so it
* can fit inside masked window. * can fit inside masked window.
*/ */
#ifdef SHAPE #ifdef USE_SHAPE
Fl_Image* img = ic->icon_image();
if(img)
icon_box = new Fl_Box(0, 0, img->w(), img->h()); icon_box = new Fl_Box(0, 0, img->w(), img->h());
else
icon_box = new Fl_Box(0, 0, w(), h());
#else #else
icon_box = new Fl_Box(0, 0, w(), h()); icon_box = new Fl_Box(0, 0, w(), h());
#endif #endif
@ -263,14 +296,19 @@ MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(),
} }
MovableIcon::~MovableIcon() { MovableIcon::~MovableIcon() {
if(mask)
XFreePixmap(fl_display, mask);
} }
void MovableIcon::show(void) { void MovableIcon::show(void) {
if(!shown()) if(!shown())
Fl_X::make_xid(this); Fl_X::make_xid(this);
#ifdef SHAPE #ifdef USE_SHAPE
Pixmap mask = create_mask(icon->icon_image()); if(icon->icon_image()) {
mask = create_mask(icon->icon_image());
if(mask)
XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet); XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet);
}
#endif #endif
} }

View File

@ -19,6 +19,8 @@
#include <FL/Fl_Button.h> #include <FL/Fl_Button.h>
#include <FL/Fl_Image.h> #include <FL/Fl_Image.h>
#include <X11/Xlib.h> // Pixmap
class GlobalIconSettings; class GlobalIconSettings;
class IconSettings; class IconSettings;
class MovableIcon; class MovableIcon;
@ -76,6 +78,7 @@ class MovableIcon : public Fl_Window {
private: private:
DesktopIcon* icon; DesktopIcon* icon;
Fl_Box* icon_box; Fl_Box* icon_box;
Pixmap mask;
public: public:
MovableIcon(DesktopIcon* i); MovableIcon(DesktopIcon* i);

View File

@ -310,23 +310,24 @@ Pixmap create_mask(Fl_Image* img) {
} }
const char* src = img->data()[0]; const char* src = img->data()[0];
unsigned char r,g,b,a; unsigned char a;
for(int y = 0; y < ih; y++) { for(int y = 0; y < ih; y++) {
for(int x = 0; x < iw; x++) { for(int x = 0; x < iw; x++) {
r = *src++; // jump rgb and pick alpha
g = *src++; src += 3;
b = *src++;
a = *src++; a = *src++;
//EDEBUG("x: %i y: %i\n", x, y); if(a < 128) {
// these are transparent
if(a < 128)
XPutPixel(xim, x, y, 0); XPutPixel(xim, x, y, 0);
else }
else {
// these are opaque
XPutPixel(xim, x, y, 1); XPutPixel(xim, x, y, 1);
} }
} }
}
Window drawable = XCreateSimpleWindow(fl_display, RootWindow(fl_display, fl_screen), 0, 0, iw, Window drawable = XCreateSimpleWindow(fl_display, RootWindow(fl_display, fl_screen), 0, 0, iw,
ih, 0, 0, BlackPixel(fl_display, fl_screen)); ih, 0, 0, BlackPixel(fl_display, fl_screen));

View File

@ -18,14 +18,35 @@
#include <FL/fl_draw.h> #include <FL/fl_draw.h>
#include <FL/x.h> #include <FL/x.h>
#define CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask) \
tmp = 0; \
if(rshift >= 0) \
tmp |= (((int)r << rshift) & rmask); \
else \
tmp |= (((int)r >> (-rshift)) & rmask); \
\
if(gshift >= 0) \
tmp |= (((int)g << gshift) & gmask); \
else \
tmp |= (((int)g >> (-gshift)) & gmask); \
\
if(bshift >= 0) \
tmp |= (((int)b << bshift) & bmask); \
else \
tmp |= (((int)b >> (-bshift)) & bmask);
Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) { Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
if(!img) if(!img)
return 0; return 0;
if(xim) { if(xim) {
if(xim->data) if(xim->data) {
delete [] xim->data; delete [] xim->data;
xim->data = 0;
}
XDestroyImage(xim); XDestroyImage(xim);
xim = 0;
} }
if(pix) if(pix)
@ -70,25 +91,26 @@ Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
n >>= 1; n >>= 1;
bshift--; bshift--;
} }
} else {
EWARNING("Depth %i not supported, for now\n", fl_visual->depth);
return 0;
} }
// assume display == 16 depth /*
xim = XCreateImage(fl_display, fl_visual->visual, 16, ZPixmap, 0, 0, img->w(), img->h(), 16, 0); * Figure out bitmap_pad and create image coresponding to the current
* display depth except for 8 bpp display
*/
int bitmap_pad = 0;
if(fl_visual->depth > 16)
bitmap_pad = 32;
else if(fl_visual->depth > 8)
bitmap_pad = 16;
else {
EWARNING("Visual %i not supported\n", xim->bits_per_pixel);
if(xim->bits_per_pixel != 16) {
EWARNING("Visual %i not implemented yet\n", xim->bits_per_pixel);
XDestroyImage(xim); XDestroyImage(xim);
xim = 0;
return 0; return 0;
} }
if(img->d() < 3) { xim = XCreateImage(fl_display, fl_visual->visual, fl_visual->depth, ZPixmap, 0, 0, img->w(), img->h(), bitmap_pad, 0);
EWARNING("Only RGB(A) images is supported for now\n");
XDestroyImage(xim);
return 0;
}
int iw = img->w(); int iw = img->w();
int ih = img->h(); int ih = img->h();
@ -105,6 +127,8 @@ Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
unsigned char* destptr = dest; unsigned char* destptr = dest;
unsigned char* src = (unsigned char*)img->data()[0]; unsigned char* src = (unsigned char*)img->data()[0];
if(xim->bits_per_pixel == 32) {
if(id == 3 || id == 4) {
for(int j = 0; j < ih; j++) { for(int j = 0; j < ih; j++) {
for(int i = 0; i < iw; i++) { for(int i = 0; i < iw; i++) {
r = *src++; r = *src++;
@ -114,26 +138,109 @@ Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
if(id == 4) if(id == 4)
src++; src++;
tmp = 0; CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask);
if(rshift >= 0)
tmp |= (((int)r << rshift) & rmask);
else
tmp |= (((int)r >> (-rshift)) & rmask);
if(gshift >= 0) if(msb) {
tmp |= (((int)g << gshift) & gmask); // big endian
else *destptr++ = (tmp & 0xff000000) >> 24;
tmp |= (((int)g >> (-gshift)) & gmask); *destptr++ = (tmp & 0xff0000) >> 16;
*destptr++ = (tmp & 0xff00) >> 8;
*destptr++ = (tmp & 0xff);
} else {
// little endian
*destptr++ = (tmp & 0xff);
*destptr++ = (tmp & 0xff00) >> 8;
*destptr++ = (tmp & 0xff0000) >> 16;
*destptr++ = (tmp & 0xff000000) >> 24;
}
}
}
} else {
for(int j = 0; j < ih; j++) {
for(int i = 0; i < iw; i++) {
r = *src++;
g = *src++;
b = *src++;
if(bshift >= 0) if(msb) {
tmp |= (((int)b << bshift) & bmask); *destptr++ = 0;
else *destptr++ = b;
tmp |= (((int)b >> (-bshift)) & bmask); *destptr++ = g;
*destptr++ = r;
} else {
*destptr++ = r;
*destptr++ = g;
*destptr++ = b;
*destptr++ = 0;
}
}
}
}
} else if(xim->bits_per_pixel == 24) {
if(id == 3 || id == 4) {
for(int j = 0; j < ih; j++) {
for(int i = 0; i < iw; i++) {
r = *src++;
g = *src++;
b = *src++;
if(id == 4)
src++;
CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask);
if(msb) {
// big endian
*destptr++ = (tmp & 0xff0000) >> 16;
*destptr++ = (tmp & 0xff00) >> 8;
*destptr++ = (tmp & 0xff);
} else {
// little endian
*destptr++ = (tmp & 0xff);
*destptr++ = (tmp & 0xff00) >> 8;
*destptr++ = (tmp & 0xff0000) >> 16;
}
}
}
} else {
for(int j = 0; j < ih; j++) {
for(int i = 0; i < iw; i++) {
r = *src++;
g = *src++;
b = *src++;
if(msb) {
// big endian
*destptr++ = b;
*destptr++ = g;
*destptr++ = r;
} else {
// little endian
*destptr++ = r;
*destptr++ = g;
*destptr++ = b;
}
}
}
}
} else if(xim->bits_per_pixel == 16) {
if(id == 3 || id == 4) {
for(int j = 0; j < ih; j++) {
for(int i = 0; i < iw; i++) {
r = *src++;
g = *src++;
b = *src++;
if(id == 4)
src++;
CALC_PIXEL(tmp, rshift, rmask, gshift, gmask, bshift, bmask);
if(msb) { if(msb) {
// big endian // big endian
*destptr++ = (tmp >> 8) & 0xff; *destptr++ = (tmp >> 8) & 0xff;
*destptr++ = (tmp & 0xff); *destptr++ = (tmp & 0xff);
} else { } else {
// little endian // little endian
*destptr++ = (tmp & 0xff); *destptr++ = (tmp & 0xff);
@ -141,6 +248,18 @@ Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
} }
} }
} }
} else {
for(int j = 0; j < ih; j++) {
for(int i = 0; i < iw; i++) {
r = *src >> 3; src++;
g = *src >> 2; src++;
b = *src >> 3; src++;
*destptr++ = r << 11 | g << 5 | b;
}
}
}
}
xim->data = (char*)dest; xim->data = (char*)dest;

View File

@ -120,8 +120,8 @@ Desktop::Desktop() : Fl_Window(0, 0, 100, 100, "") {
*/ */
begin(); begin();
wallpaper = new Wallpaper(0, 0, w(), h()); wallpaper = new Wallpaper(0, 0, w(), h());
//wallpaper->set("/home/sanel/wallpapers/katebig.jpg"); wallpaper->set("/home/sanel/wallpapers/katebig.jpg");
wallpaper->set("/home/sanelz/walls/nin/1024x768-04.jpg"); //wallpaper->set("/home/sanelz/walls/nin/1024x768-04.jpg");
//wallpaper->set("/home/sanelz/walls/nin/1024x768-02.jpg"); //wallpaper->set("/home/sanelz/walls/nin/1024x768-02.jpg");
notify = new NotifyBox(w(), h()); notify = new NotifyBox(w(), h());
notify->hide(); notify->hide();