#include #include #include #include #include #include "msgwin.h" MessageWin * msgwin_new(void) { MessageWin *p; if ((p = malloc(sizeof(*p))) == NULL) { perror("msgwin_new"); exit(1); } p->win = None; p->dpy = NULL; p->screen = NULL; p->mode = 2; p->w = p->h = 0; p->shaped = 0; p->radius = 20; p->border = 2; p->lx = 15; p->ly = 15; return p; } void msgwin_delete(MessageWin *p) { if (p) free(p); } Window msgwin_create_win(MessageWin *msg, Display *dpy, Window parent, int w, int h, u_long border, u_long bg) { XWindowAttributes attr; msg->dpy = dpy; msg->w = w + msg->radius * 4/3 + msg->lx; msg->h = h + msg->radius * 4/3 + msg->ly; msg->win = XCreateSimpleWindow(dpy, parent, 0,0, msg->w, msg->h, 0, border, bg); XGetWindowAttributes(msg->dpy, msg->win, &attr); msg->screen = attr.screen; return msg->win; } void msgwin_reattach(MessageWin *msg) { XWindowAttributes attr; XGetWindowAttributes(msg->dpy, msg->win, &attr); msg->w = attr.width; msg->h = attr.height; msg->screen = attr.screen; msg->clip_w = msg->w - msg->radius*4/3 - msg->lx; msg->clip_h = msg->h - msg->radius*4/3 - msg->ly; } void msgwin_attach_win(MessageWin *msg, Display *dpy, Window win) { msg->dpy = dpy; msg->win = win; msgwin_reattach(msg); } void msgwin_setpos(MessageWin *msg, int x, int y, int dx, int dy, int automode) { int reshape = 0; msg->o_xpos = x; msg->o_ypos = y; if (automode) { if (msg->mode == 0 || msg->mode == 2) { if (x + dx + msg->w > WidthOfScreen(msg->screen)) { msg->mode++; reshape = 1; dx = -dx; } } else { if (x - dx - msg->w < 0) { msg->mode--; reshape = 1; } else dx = -dx; } if (msg->mode == 0 || msg->mode == 1) { if (y + dy + msg->h > HeightOfScreen(msg->screen)) { msg->mode += 2; reshape = 1; dy = -dy; } } else { if (y - dy - msg->h < 0) { msg->mode -= 2; reshape = 1; } else dy = -dy; } x += dx; y += dy; } if (reshape || !msg->shaped) msgwin_reshape(msg); switch(msg->mode) { case 0: msg->xpos = x; msg->ypos = y; break; case 1: msg->xpos = x - msg->w; msg->ypos = y; break; case 2: msg->xpos = x; msg->ypos = y - msg->h; break; default: msg->xpos = x - msg->w; msg->ypos = y - msg->h; break; } } void msgwin_reshape(MessageWin *msg) { int i, w, h, r, b, lx, ly, mode; Pixmap p; GC gc; XRectangle rect[4]; /* rect[3] .. dummy */ XArc arc[4]; XPoint point[4]; w = msg->w; h = msg->h; r = msg->radius; b = msg->border; lx = msg->lx; ly = msg->ly; mode = msg->mode; p = XCreatePixmap(msg->dpy, msg->win, w, h, 1); gc = XCreateGC(msg->dpy, p, 0, NULL); XSetGraphicsExposures(msg->dpy, gc, False); XSetForeground(msg->dpy,gc,0); XFillRectangle(msg->dpy, p, gc, 0, 0, w, h); XSetForeground(msg->dpy,gc,1); rect[0].x = r; rect[0].y = 0 + b; rect[0].width = w - lx - 2 * r; rect[0].height = h - ly - b * 2; rect[1].x = b; rect[1].y = r; rect[1].width = r - b; rect[1].height = h - ly - 2 * r; rect[2].x = w - lx - r; rect[2].y = r; rect[2].width = r - b; rect[2].height = h - ly - 2 * r; arc[0].x = b; arc[0].y = b; arc[0].angle1 = 90 * 64; arc[1].x = b; arc[1].y = h - ly - 2*r + b; arc[1].angle1 = 180 * 64; arc[2].x = w - lx - 2*r + b; arc[2].y = b; arc[2].angle1 = 0; arc[3].x = w - lx - 2*r + b; arc[3].y = h - ly - 2*r + b; arc[3].angle1 = 270 * 64; for (i=0;i<4;i++) { arc[i].width = 2*r-2*b; arc[i].height = 2*r-2*b; arc[i].angle2 = 90 * 64; } msg->off_x = r*2/3; msg->off_y = r*2/3; if (lx != 0 || ly != 0) { switch(mode) { case 0: for (i=0;i<4;i++) { rect[i].x += lx; rect[i].y += ly; arc[i].x += lx; arc[i].y += ly; } point[0].x = b; point[0].y = b; point[1].x = lx+r; point[1].y = ly+r/2+b; point[2].x = lx+r/2+b; point[2].y = ly+r; msg->off_x += lx; msg->off_y += ly; break; case 1: for (i=0;i<4;i++){ rect[i].y += ly; arc[i].y += ly; } point[0].x = (w-1)-b; point[0].y = b; point[1].x = (w-1)-(lx+r); point[1].y = ly+r/2+b; point[2].x = (w-1)-(lx+r/2+b); point[2].y = ly+r; msg->off_y += ly; break; case 2: for (i=0;i<4;i++) { rect[i].x += lx; arc[i].x += lx; } point[0].x = b; point[0].y = (h-1)-b; point[1].x = lx+r; point[1].y = (h-1)-(ly+r/2+b); point[2].x = lx+r/2+b; point[2].y = (h-1)-(ly+r); msg->off_x += lx; break; default: point[0].x = (w-1)-b; point[0].y = (h-1)-b; point[1].x = (w-1)-(lx+r); point[1].y = (h-1)-(ly+r/2+b); point[2].x = (w-1)-(lx+r/2+b); point[2].y = (h-1)-(ly+r); break; } XFillPolygon(msg->dpy, p, gc, point, 3, Complex, CoordModeOrigin); } XFillRectangles(msg->dpy, p, gc, rect, 3); XFillArcs(msg->dpy, p, gc, arc, 4); XShapeCombineMask(msg->dpy, msg->win, ShapeClip, 0, 0, p, ShapeSet); XSetForeground(msg->dpy,gc,1); rect[0].y -= b; rect[0].height += b*2; rect[1].x -= b; rect[1].width += b; rect[2].width += b; for (i=0;i<4;i++) { arc[i].x -= b; arc[i].y -= b; arc[i].width = arc[i].height = 2*r; } if (lx != 0 || ly != 0) { switch(mode) { case 0: point[0].x = 0; point[0].y = b/2; point[1].x = b/2; point[1].y = 0; point[2].x = lx+r; point[2].y = ly+r/2; point[3].x = lx+r/2; point[3].y = ly+r; break; case 1: point[0].x = (w-1); point[0].y = b/2; point[1].x = (w-1)-(b/2); point[1].y = 0; point[2].x = (w-1)-(lx+r); point[2].y = ly+r/2; point[3].x = (w-1)-(lx+r/2); point[3].y = ly+r; break; case 2: point[0].x = 0; point[0].y = (h-1)-(b/2); point[1].x = b/2; point[1].y = (h-1); point[2].x = lx+r; point[2].y = (h-1)-(ly+r/2); point[3].x = lx+r/2; point[3].y = (h-1)-(ly+r); break; default: point[0].x = (w-1); point[0].y = (h-1)-(b/2); point[1].x = (w-1)-(b/2); point[1].y = (h-1); point[2].x = (w-1)-(lx+r); point[2].y = (h-1)-(ly+r/2); point[3].x = (w-1)-(lx+r/2); point[3].y = (h-1)-(ly+r); break; } XFillPolygon(msg->dpy, p, gc, point, 4, Complex, CoordModeOrigin); } XFillRectangles(msg->dpy, p, gc, rect, 3); XFillArcs(msg->dpy, p, gc, arc, 4); XShapeCombineMask(msg->dpy, msg->win, ShapeBounding, 0, 0, p, ShapeSet); XFreePixmap(msg->dpy,p); XFreeGC(msg->dpy,gc); msg->shaped = 1; }