#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define max(a,b) ((a>b)?a:b) #define FontName "Bitstream Vera Sans Mono:size=12:style=Roman" #define Text "Icon" #define OpaqueMask 0xffffffff #define RedMask 0x00ff0000 #define GreenMask 0x0000ff00 #define BlueMask 0x000000ff #define ColorMask 0x00ffffff #define AlphaMask 0xff000000 #define TransBdry 0x48 typedef struct _X { Display *dpy; Window win, root; Visual *visual; Colormap colmap; GC gc; XGCValues values; XEvent event; Cursor cursor; XftFont *XFTFont; XRenderColor XRcolor; XftColor XFTcolor; XftDraw *draw; XGlyphInfo ext; XRenderPictureAttributes wprop; XSetWindowAttributes attr; Damage damage; XserverRegion region; int render_event, render_error; int composite_major, composite_minor; int composite_opcode, composite_event, composite_error; int xfixes_event, xfixes_error; int event_base, event_error; int error_base, damage_event, damage_error; unsigned long wmask; int run, scr; Picture Root, Image, Mask; } Server, *ServerPtr; typedef struct _im { int w, h; XImage *xIm, *xMask, *xShape; XImage *xtIm, *xtMask; } Im, *ImPtr; int win_width, win_height; int tWidth, tHeight; /* * Proptotypes */ unsigned short XlibInit(ServerPtr x); Visual *XlibAllocVisual (Display *dpy, int scr); void XlibSetWindowName(Display *dpy, Window win, int width, int height, const char *HintRes, const char *HintClass, const char *AppName); void XlibEventLoop(ServerPtr x, ImPtr im); Picture XlibCreateImage(ServerPtr x, ImPtr im); Picture XlibCreateMask(ServerPtr x, ImPtr im); unsigned short XlibInit(ServerPtr x) { char *display_string=NULL; display_string = getenv("DISPLAY"); if (!(x->dpy = (Display*) XOpenDisplay(display_string))) { fprintf(stderr, "Couldn't open display '%s'\n", (display_string ? display_string : "NULL")); return 1; } x->scr = DefaultScreen(x->dpy); if (!XRenderQueryExtension (x->dpy, &x->render_event, &x->render_error)){ fprintf (stderr, "No render extension\n"); return 1; } if (!XQueryExtension (x->dpy, COMPOSITE_NAME, &x->composite_opcode, &x->composite_event, &x->composite_error)){ fprintf (stderr, "No composite extension\n"); return 1; } XCompositeQueryVersion (x->dpy, &x->composite_major, &x->composite_minor); if (False == XShapeQueryExtension(x->dpy, &x->event_base, &x->error_base)) { fprintf(stderr, "Display '%s' does NOT support XShape\n", (display_string ? display_string : "NULL")); return 1; } if (!XDamageQueryExtension (x->dpy, &x->damage_event, &x->damage_error)) return 1; if (!XFixesQueryExtension (x->dpy, &x->xfixes_event, &x->xfixes_error)) return 1; XCompositeRedirectSubwindows(x->dpy, RootWindow(x->dpy, x->scr), CompositeRedirectAutomatic); x->visual = XlibAllocVisual(x->dpy, x->scr); if(!x->visual) return 1; x->colmap = XCreateColormap (x->dpy, RootWindow(x->dpy, x->scr), x->visual, AllocNone); x->XFTFont = XftFontOpenName(x->dpy, x->scr, FontName); if(!x->XFTFont){ fprintf(stderr, "Unable create Xft FontSet for FontName: \"%s\"\n", (char*) FontName); return 1; } x->root = RootWindow(x->dpy, x->scr); x->run = 1; return 0; } Visual * XlibAllocVisual (Display *dpy, int scr) { XVisualInfo *xvi; XVisualInfo template; int nvi, i; XRenderPictFormat *format; Visual *visual; template.screen = scr; template.depth = 32; template.class = TrueColor; xvi = XGetVisualInfo (dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &template, &nvi); if (xvi == NULL) return NULL; visual = NULL; for (i = 0; i < nvi; i++) { format = XRenderFindVisualFormat (dpy, xvi[i].visual); if (format->type == PictTypeDirect && format->direct.alphaMask) { visual = xvi[i].visual; break; } } XFree (xvi); return visual; } void XlibSetWindowName(Display *dpy, Window win, int width, int height, const char *HintRes, const char *HintClass, const char *AppName) { XSizeHints *size_hints; XWMHints *wm_hints; XClassHint *class_hint; size_hints = XAllocSizeHints (); size_hints->flags = 0; size_hints->x = 0; size_hints->y = 0; size_hints->width = width; size_hints->height = height; wm_hints = XAllocWMHints(); wm_hints->flags = InputHint; wm_hints->input = True; class_hint = XAllocClassHint (); class_hint->res_name = (char*)HintRes; class_hint->res_class = (char*)HintClass; Xutf8SetWMProperties (dpy, win, AppName, AppName, 0, 0, size_hints, wm_hints, class_hint); XFree (size_hints); XFree (wm_hints); XFree (class_hint); } ImPtr ReadImage(ServerPtr x) { double AlphaComp, RedComp, GreenComp, BlueComp; unsigned int alpha, red, green, blue; int32_t *ColorBuffer, *AlphaBuffer; int8_t *ShapeBuffer; int i, j; int *data; Imlib_Image im; ImPtr tmp = (ImPtr)malloc(sizeof(Im)); im = imlib_load_image("Firefox.gif"); imlib_context_set_image(im); tmp->w = imlib_image_get_width(); tmp->h = imlib_image_get_height(); data = imlib_image_get_data_for_reading_only(); imlib_free_image(); ColorBuffer = malloc(tmp->w*tmp->h*sizeof(int32_t*)); AlphaBuffer = malloc(tmp->w*tmp->h*sizeof(int32_t*)); ShapeBuffer = malloc(tmp->w*tmp->h*sizeof(int8_t*)); for(i=0; iw; i++) for(j=0; jh; j++) { /* Compute Color Table */ AlphaComp = (AlphaMask / 255.0); RedComp = (x->visual->red_mask / 255.0); GreenComp = (x->visual->green_mask / 255.0); BlueComp = (x->visual->blue_mask / 255.0); alpha = (((data[i*tmp->w+j] & AlphaMask)>>24) * AlphaComp); red = (((data[i*tmp->w+j] & RedMask)>>16) * RedComp); green = (((data[i*tmp->w+j] & GreenMask)>>8) * GreenComp); blue = ((data[i*tmp->w+j] & BlueMask) * BlueComp); red &= x->visual->red_mask; green &= x->visual->green_mask; blue &= x->visual->blue_mask; if((alpha>>24) == 0) ColorBuffer[i*tmp->w+j] = AlphaMask; else{ ColorBuffer[i*tmp->w+j] = (((alpha!=AlphaMask) ? AlphaMask:alpha) | red | green | blue); } /* Fill AlphaBuffer */ AlphaBuffer[i*tmp->w+j] = alpha; /* Fill ShapeBuffer */ ShapeBuffer[i*tmp->w+j] = (((alpha>>24) == 0)?0:1); } tmp->xIm = XCreateImage(x->dpy, x->visual, 32, ZPixmap, 0, (char*)ColorBuffer, tmp->w, tmp->h, 32, tmp->h*4); tmp->xMask = XCreateImage(x->dpy, x->visual, 32, ZPixmap, 0, (char*)AlphaBuffer, tmp->w, tmp->h, 32, tmp->h*4); tmp->xShape = (XImage*)malloc(sizeof(XImage)); tmp->xShape->width = tmp->w; tmp->xShape->height = tmp->h; tmp->xShape->xoffset = 0; tmp->xShape->format = ZPixmap; tmp->xShape->data = (char*)ShapeBuffer; tmp->xShape->byte_order = LSBFirst; tmp->xShape->bitmap_unit = 32; tmp->xShape->bitmap_bit_order = LSBFirst; tmp->xShape->bitmap_pad = 8; tmp->xShape->depth = 1; tmp->xShape->bytes_per_line = 0; /* Let XInitImage guess it */ tmp->xShape->bits_per_pixel = 8; tmp->xShape->red_mask = 0xff; tmp->xShape->green_mask = 0xff; tmp->xShape->blue_mask = 0xff; XInitImage(tmp->xShape); return (ImPtr)tmp; } int main() { ImPtr im; ServerPtr x = (ServerPtr)malloc(sizeof(Server)); if(XlibInit(x)) { printf("Error\n"); exit(1); } XftTextExtents8 (x->dpy, x->XFTFont, (XftChar8*)Text, strlen(Text), &x->ext); im = ReadImage(x); x->attr.override_redirect = 1; x->attr.background_pixel = 0; x->attr.colormap = x->colmap; x->attr.border_pixel = 0; x->attr.event_mask = ExposureMask | StructureNotifyMask | ButtonPressMask | Button1MotionMask | ButtonReleaseMask | Button1MotionMask; x->wmask = CWEventMask | CWBackPixel | CWColormap | CWOverrideRedirect | CWBorderPixel; tWidth = x->ext.width; tHeight = (x->XFTFont->ascent + x->XFTFont->descent); win_width = im->w; win_height = im->h + tHeight + 4; x->win = XCreateWindow(x->dpy, RootWindow(x->dpy, 0), 30, 30, win_width, win_height, 0, 32, InputOutput, x->visual, x->wmask, &x->attr); XlibSetWindowName(x->dpy, x->win, x->ext.width, x->ext.height, "haber", "Icon label", "svmatra"); x->cursor = XCreateFontCursor (x->dpy, XC_hand2); XDefineCursor(x->dpy, x->win, x->cursor); XMapWindow(x->dpy, x->win); XLowerWindow(x->dpy, x->win); x->gc = XCreateGC(x->dpy, x->win, 0, 0); XlibEventLoop(x, im); /* Free and exit */ XRenderFreePicture(x->dpy, x->Image); XRenderFreePicture(x->dpy, x->Mask); free(im->xIm->data); free(im->xMask->data); XFree(im->xIm); XFree(im->xMask); XDestroyWindow(x->dpy, x->win); XCloseDisplay(x->dpy); return 0; } void XlibHandleExpose(ServerPtr x, ImPtr im) { x->Root = XRenderCreatePicture(x->dpy, x->win, XRenderFindVisualFormat(x->dpy, x->visual), 0, 0); x->Image = XlibCreateImage(x, im); x->Mask = XlibCreateMask(x, im); XRenderComposite(x->dpy, PictOpOver, x->Image, x->Mask, x->Root, 0, 0, 0, 0, 0, 0, win_width, win_height); return; } Picture XlibCreateMask(ServerPtr x, ImPtr im) { Picture Image; Pixmap Pix; GC gc; int ww, wh, tw, th; tw = x->ext.width; th = (x->XFTFont->ascent + x->XFTFont->descent); ww = im->w; wh = im->h + th + 4; Pix = XCreatePixmap(x->dpy, x->root, ww, wh, 32); gc = XCreateGC(x->dpy, Pix, 0, 0); XSetForeground(x->dpy, gc, 0); XFillRectangle(x->dpy, Pix, gc, 0, 0, ww, wh); XPutImage(x->dpy, Pix, gc, im->xMask, 0, 0, 0, 0, im->w, im->h); XSetForeground(x->dpy, gc, 0xff000000); XFillRectangle(x->dpy, Pix, gc, (ww/2 - ((ww-th)/2)), im->h + 4, tw+2, th); Image = XRenderCreatePicture(x->dpy, Pix, XRenderFindVisualFormat(x->dpy, x->visual), 0, 0); XFreeGC(x->dpy, gc); XFreePixmap(x->dpy, Pix); return (Picture)Image; } Picture XlibCreateImage(ServerPtr x, ImPtr im) { Picture Image; Pixmap Pix, TextPix; GC gc; int ww, wh, tw, th; tw = x->ext.width; th = (x->XFTFont->ascent + x->XFTFont->descent); ww = im->w; wh = im->h + th + 4; Pix = XCreatePixmap(x->dpy, x->root, ww, wh, 32); gc = XCreateGC(x->dpy, Pix, 0, 0); XSetForeground(x->dpy, gc, 0xff000000); XFillRectangle(x->dpy, Pix, gc, 0, 0, ww, wh); XPutImage(x->dpy, Pix, gc, im->xIm, 0, 0, 0, 0, im->w, im->h); /* Text first */ TextPix = XCreatePixmap(x->dpy, x->root, tw+2, th, 32); x->draw = XftDrawCreate(x->dpy, TextPix, x->visual, x->colmap); x->XRcolor.red = 0; x->XRcolor.green = 0; x->XRcolor.blue = 0; x->XRcolor.alpha = 0; XftColorAllocValue(x->dpy, x->visual, x->colmap, &x->XRcolor, &x->XFTcolor); XftDrawRect (x->draw, &x->XFTcolor, 0, 0, tw+2, th); XftColorFree(x->dpy, x->visual, x->colmap, &x->XFTcolor); x->XRcolor.red = 0xffff; x->XRcolor.green = 0xffff; x->XRcolor.blue = 0xffff; x->XRcolor.alpha = 0xffff; XftColorAllocValue(x->dpy, x->visual, x->colmap, &x->XRcolor, &x->XFTcolor); XftDrawString8(x->draw, &x->XFTcolor, x->XFTFont, 0, th-4, (XftChar8*)Text, strlen(Text)); XCopyArea(x->dpy, TextPix, Pix, gc, 0, 0, tw+2, th, (ww/2 - ((ww-th)/2)), im->h+4); Image = XRenderCreatePicture(x->dpy, Pix, XRenderFindVisualFormat(x->dpy, x->visual), 0, 0); XFreeGC(x->dpy, gc); XFreePixmap(x->dpy, Pix); XFreePixmap(x->dpy, TextPix); XftColorFree(x->dpy, x->visual, x->colmap, &x->XFTcolor); return (Picture)Image; } void XlibEventLoop(ServerPtr x, ImPtr im) { int X=0, Y=0; while (x->run) { XNextEvent(x->dpy, &x->event); switch (x->event.type) { case Expose: XlibHandleExpose(x, im); break; case ButtonPress: if(x->event.xbutton.button == 3) x->run = 0; if(x->event.xbutton.button == 1) { X = x->event.xbutton.x; Y = x->event.xbutton.y; } break; case MotionNotify: XMoveWindow(x->dpy, x->event.xbutton.window, max(X, x->event.xmotion.x_root) ? (x->event.xmotion.x_root - X) : (X - x->event.xmotion.x_root), max(Y, x->event.xmotion.y_root) ? (x->event.xmotion.y_root - Y) : (Y - x->event.xmotion.y_root)); break; } } return; }