mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Root pixmap is set when wallpaper is choosed (pseudo transparency).
When icons are moved, correct shape is applied on that window. ...maybe something forgot to add...
This commit is contained in:
parent
84339d9232
commit
c153f4f114
@ -34,8 +34,10 @@
|
||||
// label offset from icon y()+h(), so selection box can be drawn nicely
|
||||
#define LABEL_OFFSET 2
|
||||
|
||||
#define SHAPE 1
|
||||
|
||||
DesktopIcon::DesktopIcon(GlobalIconSettings* gs, IconSettings* is, int bg) :
|
||||
Fl_Button(is->x, is->y, ICONSIZE, ICONSIZE) {
|
||||
Fl_Widget(is->x, is->y, ICONSIZE, ICONSIZE) {
|
||||
|
||||
EASSERT(gs != NULL);
|
||||
|
||||
@ -214,7 +216,29 @@ void DesktopIcon::draw(void) {
|
||||
}
|
||||
|
||||
int DesktopIcon::handle(int event) {
|
||||
return Fl_Button::handle(event);
|
||||
switch(event) {
|
||||
case FL_FOCUS:
|
||||
case FL_UNFOCUS:
|
||||
case FL_ENTER:
|
||||
case FL_LEAVE:
|
||||
return 1;
|
||||
/*
|
||||
* We have to handle FL_MOVE too, if want to get only once
|
||||
* FL_ENTER when entered or FL_LEAVE when leaved.
|
||||
*/
|
||||
case FL_MOVE:
|
||||
return 1;
|
||||
case FL_PUSH:
|
||||
return 1;
|
||||
case FL_RELEASE:
|
||||
if(Fl::event_clicks() > 0)
|
||||
EDEBUG(ESTRLOC ": EXECUTE: %s\n", settings->cmd.c_str());
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(), ic->h()), icon(ic) {
|
||||
@ -224,7 +248,16 @@ MovableIcon::MovableIcon(DesktopIcon* ic) : Fl_Window(ic->x(), ic->y(), ic->w(),
|
||||
color(ic->color());
|
||||
|
||||
begin();
|
||||
Fl_Image* img = ic->icon_image();
|
||||
/*
|
||||
* Force box be same width/height as icon so it
|
||||
* can fit inside masked window.
|
||||
*/
|
||||
#ifdef SHAPE
|
||||
icon_box = new Fl_Box(0, 0, img->w(), img->h());
|
||||
#else
|
||||
icon_box = new Fl_Box(0, 0, w(), h());
|
||||
#endif
|
||||
icon_box->image(ic->icon_image());
|
||||
end();
|
||||
}
|
||||
@ -235,8 +268,9 @@ MovableIcon::~MovableIcon() {
|
||||
void MovableIcon::show(void) {
|
||||
if(!shown())
|
||||
Fl_X::make_xid(this);
|
||||
#if 0
|
||||
Pixmap mask = create_mask((Fl_RGB_Image*)icon->icon_image());
|
||||
|
||||
#ifdef SHAPE
|
||||
Pixmap mask = create_mask(icon->icon_image());
|
||||
XShapeCombineMask(fl_display, fl_xid(this), ShapeBounding, 0, 0, mask, ShapeSet);
|
||||
#endif
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class GlobalIconSettings;
|
||||
class IconSettings;
|
||||
class MovableIcon;
|
||||
|
||||
class DesktopIcon : public Fl_Button {
|
||||
class DesktopIcon : public Fl_Widget {
|
||||
private:
|
||||
IconSettings* settings;
|
||||
const GlobalIconSettings* globals;
|
||||
|
@ -23,6 +23,7 @@ Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP = 0;
|
||||
Atom _XA_NET_NUMBER_OF_DESKTOPS = 0;
|
||||
Atom _XA_NET_CURRENT_DESKTOP = 0;
|
||||
Atom _XA_NET_DESKTOP_NAMES = 0;
|
||||
Atom _XA_XROOTPMAP_ID = 0;
|
||||
|
||||
Atom _XA_EDE_DESKTOP_NOTIFY = 0;
|
||||
Atom _XA_EDE_DESKTOP_NOTIFY_COLOR = 0;
|
||||
@ -43,6 +44,7 @@ void init_atoms(void) {
|
||||
_XA_NET_NUMBER_OF_DESKTOPS = XInternAtom(fl_display, "_NET_NUMBER_OF_DESKTOPS", False);
|
||||
_XA_NET_CURRENT_DESKTOP = XInternAtom(fl_display, "_NET_CURRENT_DESKTOP", False);
|
||||
_XA_NET_DESKTOP_NAMES = XInternAtom(fl_display, "_NET_DESKTOP_NAMES", False);
|
||||
_XA_XROOTPMAP_ID = XInternAtom(fl_display, "_XROOTPMAP_ID", False);
|
||||
|
||||
_XA_EDE_DESKTOP_NOTIFY = XInternAtom(fl_display, "_EDE_DESKTOP_NOTIFY", False);
|
||||
_XA_EDE_DESKTOP_NOTIFY_COLOR = XInternAtom(fl_display, "_EDE_DESKTOP_NOTIFY_COLOR", False);
|
||||
@ -288,6 +290,64 @@ void set_xoverlay_drawable(Fl_Window* win) {
|
||||
overlay_drawable = win;
|
||||
}
|
||||
|
||||
Pixmap create_mask(Fl_Image* img) {
|
||||
if(!img)
|
||||
return 0;
|
||||
|
||||
// no alpha
|
||||
if(img->d() != 4)
|
||||
return 0;
|
||||
|
||||
int iw = img->w();
|
||||
int ih = img->h();
|
||||
|
||||
unsigned char* xim_data = new unsigned char[((iw >> 3) + 8) * ih];
|
||||
|
||||
XImage* xim = XCreateImage(fl_display, fl_visual->visual, 1, ZPixmap, 0, (char*)xim_data, iw, ih, 8, 0);
|
||||
if(!xim) {
|
||||
delete [] xim_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* src = img->data()[0];
|
||||
unsigned char r,g,b,a;
|
||||
|
||||
for(int y = 0; y < ih; y++) {
|
||||
for(int x = 0; x < iw; x++) {
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
a = *src++;
|
||||
|
||||
//EDEBUG("x: %i y: %i\n", x, y);
|
||||
|
||||
if(a < 128)
|
||||
XPutPixel(xim, x, y, 0);
|
||||
else
|
||||
XPutPixel(xim, x, y, 1);
|
||||
}
|
||||
}
|
||||
|
||||
Window drawable = XCreateSimpleWindow(fl_display, RootWindow(fl_display, fl_screen), 0, 0, iw,
|
||||
ih, 0, 0, BlackPixel(fl_display, fl_screen));
|
||||
|
||||
Pixmap pix = XCreatePixmap(fl_display, drawable, iw, ih, 1);
|
||||
|
||||
XGCValues gcv;
|
||||
gcv.graphics_exposures = False;
|
||||
GC dgc = XCreateGC(fl_display, pix, GCGraphicsExposures, &gcv);
|
||||
|
||||
XPutImage(fl_display, pix, dgc, xim, 0, 0, 0, 0, iw, ih);
|
||||
|
||||
XDestroyWindow(fl_display, drawable);
|
||||
XFreeGC(fl_display, dgc);
|
||||
delete [] xim->data;
|
||||
xim->data = 0;
|
||||
XDestroyImage(xim);
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
char* get_basename(const char* path) {
|
||||
char* p = strrchr(path, '/');
|
||||
if(p)
|
||||
|
@ -24,6 +24,7 @@ extern Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;
|
||||
extern Atom _XA_NET_NUMBER_OF_DESKTOPS;
|
||||
extern Atom _XA_NET_CURRENT_DESKTOP;
|
||||
extern Atom _XA_NET_DESKTOP_NAMES;
|
||||
extern Atom _XA_XROOTPMAP_ID;
|
||||
|
||||
// via XGetTextProperty/XSetTextProperty
|
||||
extern Atom _XA_EDE_DESKTOP_NOTIFY;
|
||||
@ -45,7 +46,7 @@ void draw_xoverlay(int x, int y, int w, int h);
|
||||
void clear_xoverlay(void);
|
||||
void set_xoverlay_drawable(Fl_Window* win);
|
||||
|
||||
Pixmap create_mask(Fl_RGB_Image* img);
|
||||
Pixmap create_mask(Fl_Image* img);
|
||||
|
||||
char* get_basename(const char* path);
|
||||
|
||||
|
@ -11,15 +11,174 @@
|
||||
*/
|
||||
|
||||
#include "Wallpaper.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <edelib/Debug.h>
|
||||
#include <FL/Fl_Shared_Image.h>
|
||||
#include <FL/fl_draw.h>
|
||||
#include <FL/x.h>
|
||||
|
||||
Wallpaper::Wallpaper(int X, int Y, int W, int H) : Fl_Box(X, Y, W, H, 0), img(NULL), tiled(false) {
|
||||
Pixmap create_xpixmap(Fl_Image* img, XImage* xim, Pixmap pix) {
|
||||
if(!img)
|
||||
return 0;
|
||||
|
||||
if(xim) {
|
||||
if(xim->data)
|
||||
delete [] xim->data;
|
||||
XDestroyImage(xim);
|
||||
}
|
||||
|
||||
if(pix)
|
||||
XFreePixmap(fl_display, pix);
|
||||
|
||||
unsigned long rmask = fl_visual->visual->red_mask;
|
||||
unsigned long gmask = fl_visual->visual->green_mask;
|
||||
unsigned long bmask = fl_visual->visual->blue_mask;
|
||||
unsigned long start_mask;
|
||||
int start_shift;
|
||||
int rshift = 0;
|
||||
int gshift = 0;
|
||||
int bshift = 0;
|
||||
|
||||
if(fl_visual->depth == 24 || fl_visual->depth == 16) {
|
||||
unsigned long n;
|
||||
if(fl_visual->depth == 24) {
|
||||
start_shift = 24;
|
||||
start_mask = 0x80000000;
|
||||
} else {
|
||||
start_shift = 8;
|
||||
start_mask = 0x8000;
|
||||
}
|
||||
|
||||
rshift = start_shift;
|
||||
n = start_mask;
|
||||
while(!(n & rmask)) {
|
||||
n >>= 1;
|
||||
rshift--;
|
||||
}
|
||||
|
||||
gshift = start_shift;
|
||||
n = start_mask;
|
||||
while(!(n & gmask)) {
|
||||
n >>= 1;
|
||||
gshift--;
|
||||
}
|
||||
|
||||
bshift = start_shift;
|
||||
n = start_mask;
|
||||
while(!(n & bmask)) {
|
||||
n >>= 1;
|
||||
bshift--;
|
||||
}
|
||||
}
|
||||
|
||||
// assume display == 16 depth
|
||||
xim = XCreateImage(fl_display, fl_visual->visual, 16, ZPixmap, 0, 0, img->w(), img->h(), 16, 0);
|
||||
|
||||
if(xim->bits_per_pixel != 16) {
|
||||
EWARNING("Visual %i not implemented yet\n", xim->bits_per_pixel);
|
||||
XDestroyImage(xim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(img->d() < 3) {
|
||||
EWARNING("Only RGB(A) images is supported for now\n");
|
||||
XDestroyImage(xim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iw = img->w();
|
||||
int ih = img->h();
|
||||
int id = img->d();
|
||||
|
||||
bool msb = false;
|
||||
if(ImageByteOrder(fl_display) == MSBFirst)
|
||||
msb = true;
|
||||
else
|
||||
msb = false;
|
||||
|
||||
unsigned int r, g, b, tmp;
|
||||
unsigned char* dest = new unsigned char[iw * ih * id];
|
||||
unsigned char* destptr = dest;
|
||||
unsigned char* src = (unsigned char*)img->data()[0];
|
||||
|
||||
for(int j = 0; j < ih; j++) {
|
||||
for(int i = 0; i < iw; i++) {
|
||||
r = *src++;
|
||||
g = *src++;
|
||||
b = *src++;
|
||||
|
||||
if(id == 4)
|
||||
src++;
|
||||
|
||||
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);
|
||||
|
||||
if(msb) {
|
||||
// big endian
|
||||
*destptr++ = (tmp >> 8) & 0xff;
|
||||
*destptr++ = (tmp & 0xff);
|
||||
} else {
|
||||
// little endian
|
||||
*destptr++ = (tmp & 0xff);
|
||||
*destptr++ = (tmp >> 8) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xim->data = (char*)dest;
|
||||
|
||||
/*
|
||||
* Creating another window as drawable is needed since fl_window (as drawable) can't be
|
||||
* used here (valid only in draw()).
|
||||
*/
|
||||
Window drawable = XCreateSimpleWindow(fl_display, RootWindow(fl_display, fl_screen), 0, 0, iw,
|
||||
ih, 0, 0, BlackPixel(fl_display, fl_screen));
|
||||
|
||||
pix = XCreatePixmap(fl_display, drawable, iw, ih, fl_visual->depth);
|
||||
|
||||
/*
|
||||
* The same applies as above;
|
||||
* fl_gc can't be used here.
|
||||
*/
|
||||
XGCValues gcv;
|
||||
gcv.graphics_exposures = False;
|
||||
GC dgc = XCreateGC(fl_display, pix, GCGraphicsExposures, &gcv);
|
||||
|
||||
XPutImage(fl_display, pix, dgc, xim, 0, 0, 0, 0, iw, ih);
|
||||
|
||||
XDestroyWindow(fl_display, drawable);
|
||||
XFreeGC(fl_display, dgc);
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
Wallpaper::Wallpaper(int X, int Y, int W, int H) :
|
||||
Fl_Box(X, Y, W, H, 0), rootpmap_image(NULL), rootpmap_pixmap(0), img(NULL), tiled(false) {
|
||||
}
|
||||
|
||||
Wallpaper::~Wallpaper() {
|
||||
if(rootpmap_image) {
|
||||
if(rootpmap_image->data)
|
||||
delete [] rootpmap_image->data;
|
||||
XDestroyImage(rootpmap_image);
|
||||
}
|
||||
|
||||
if(rootpmap_pixmap)
|
||||
XFreePixmap(fl_display, rootpmap_pixmap);
|
||||
}
|
||||
|
||||
bool Wallpaper::set(const char* path) {
|
||||
@ -33,6 +192,8 @@ bool Wallpaper::set(const char* path) {
|
||||
img = i;
|
||||
image(img);
|
||||
|
||||
set_rootpmap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -43,6 +204,46 @@ bool Wallpaper::set_tiled(const char* path) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Wallpaper::set_rootpmap(void) {
|
||||
if(!image())
|
||||
return;
|
||||
|
||||
rootpmap_pixmap = create_xpixmap(image(), rootpmap_image, rootpmap_pixmap);
|
||||
|
||||
if(!rootpmap_pixmap)
|
||||
return;
|
||||
|
||||
XChangeProperty(fl_display, RootWindow(fl_display, fl_screen),
|
||||
_XA_XROOTPMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&rootpmap_pixmap, 1);
|
||||
|
||||
#if 0
|
||||
XGCValues gcv;
|
||||
gcv.graphics_exposures = False;
|
||||
GC dgc = XCreateGC(fl_display, pix, GCGraphicsExposures, &gcv);
|
||||
|
||||
XImage img;
|
||||
img.byte_order = LSBFirst; // TODO: check
|
||||
img.format = ZPixmap;
|
||||
img.depth = fl_visual->depth; // depth of screen or depth of image() ?
|
||||
|
||||
// find out bits_per_pixel field
|
||||
int num_pfv;
|
||||
XPixmapFormatValues* pfv = 0;
|
||||
XPixmapFormatValues* pfvlst = 0;
|
||||
pfvlst = XListPixmapFormats(fl_display, &num_pfv);
|
||||
for(pfv = pfvlst; pfv < pfvlst + num_pfv; pfv++) {
|
||||
if(pfv->depth == fl_visual->depth)
|
||||
break;
|
||||
}
|
||||
|
||||
img.bits_per_pixel = pfv->bits_per_pixel;
|
||||
if(img.bits_per_pixel & 7) {
|
||||
EWARNING("Can't work with %i bpp !!!\n", img.bits_per_pixel);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Wallpaper::draw(void) {
|
||||
if(!image())
|
||||
return;
|
||||
@ -84,4 +285,25 @@ void Wallpaper::draw(void) {
|
||||
}
|
||||
|
||||
im->draw(ix, iy);
|
||||
|
||||
/*
|
||||
* For debugging purposes :)
|
||||
* Uncommenting this (and removing GC/Window creation in create_xpixmap
|
||||
* will draw _XA_XROOTPMAP_ID Pixmap directly in Wallpaper widget.
|
||||
* It is used to check Fl_Image->Image conversion.
|
||||
*/
|
||||
#if 0
|
||||
if(global_xim) {
|
||||
Pixmap pix = fl_create_offscreen(image()->w(), image()->h());
|
||||
fl_begin_offscreen(pix);
|
||||
XPutImage(fl_display, pix, fl_gc, global_xim, 0, 0, 0, 0, image()->w(), image()->h());
|
||||
fl_end_offscreen();
|
||||
|
||||
fl_copy_offscreen(ix, iy, image()->w(), image()->h(), pix, 0, 0);
|
||||
|
||||
XChangeProperty(fl_display, RootWindow(fl_display, fl_screen),
|
||||
_XA_XROOTPMAP_ID, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pix, 1);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -16,14 +16,19 @@
|
||||
#include <FL/Fl_Box.h>
|
||||
#include <FL/Fl_Image.h>
|
||||
|
||||
#include <X11/Xlib.h> // XImage, Pixmap
|
||||
|
||||
/*
|
||||
* Class responsible for displaying images at background
|
||||
* their scaling (TODO), caching(TODO) and making coffee at spear time.
|
||||
*/
|
||||
class Wallpaper : public Fl_Box {
|
||||
private:
|
||||
XImage* rootpmap_image;
|
||||
Pixmap rootpmap_pixmap;
|
||||
Fl_Image* img;
|
||||
bool tiled;
|
||||
void set_rootpmap(void);
|
||||
|
||||
public:
|
||||
Wallpaper(int X, int Y, int W, int H);
|
||||
|
@ -87,10 +87,16 @@ int desktop_xmessage_handler(int event) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(fl_xevent->xclient.message_type == _XA_EDE_DESKTOP_NOTIFY_COLOR) {
|
||||
//if(fl_xevent->xclient.message_type == _XA_EDE_DESKTOP_NOTIFY_COLOR) {
|
||||
if(fl_xevent->xproperty.atom == _XA_EDE_DESKTOP_NOTIFY_COLOR) {
|
||||
Desktop::instance()->notify_box_color(ede_get_desktop_notify_color());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(fl_xevent->xproperty.atom == _XA_NET_WORKAREA) {
|
||||
Desktop::instance()->update_workarea();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -114,7 +120,9 @@ Desktop::Desktop() : Fl_Window(0, 0, 100, 100, "") {
|
||||
*/
|
||||
begin();
|
||||
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-02.jpg");
|
||||
notify = new NotifyBox(w(), h());
|
||||
notify->hide();
|
||||
end();
|
||||
|
Loading…
Reference in New Issue
Block a user