1 diff -U3 -r fvwm/borders.c fvwm/borders.c
2 --- fvwm/borders.c 2011-12-09 20:59:40.674170242 +0100
3 +++ fvwm/borders.c 2011-12-09 21:31:27.171864221 +0100
6 xgcv.fill_style = FillSolid;
7 valuemask = GCFillStyle;
9 if (!bg->flags.use_pixmap)
12 @@ -1839,13 +1840,26 @@
14 static void border_get_border_background(
15 pixmap_background_type *bg, common_decorations_type *cd,
16 - rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w, window_parts part)
17 + rectangle *part_g, rectangle *relative_g, int *free_bg_pixmap, Window w, window_parts part, FvwmPicture *fp)
19 *free_bg_pixmap = False;
21 - if (cd->texture_pixmap)
24 bg->flags.use_pixmap = 1;
25 + bg->pixmap.p = fp->picture;
26 + bg->pixmap.g.width = fp->width;
27 + bg->pixmap.g.height = fp->height;
28 + bg->pixmap.shape = None;
29 + bg->pixmap.alpha = None;
30 + bg->pixmap.depth = fp->depth;
31 + bg->pixmap.flags.is_tiled = 1;
32 + bg->pixmap.flags.is_stretched = 0;
33 + bg->pixmap.fra.mask = 0;
35 + else if (cd->texture_pixmap)
37 + bg->flags.use_pixmap = 1;
38 bg->pixmap.p = cd->texture_pixmap;
39 bg->pixmap.g.width = cd->texture_pixmap_width;
40 bg->pixmap.g.height = cd->texture_pixmap_height;
41 @@ -1940,6 +1954,18 @@
45 +#define DRAWBORDER(PIX,X,Y,WIDTH,HEIGHT) \
47 + fp = df->u.mb.pixmaps[PIX]; \
48 + border_get_border_background( \
49 + &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, PART_NONE, fp); \
53 + r.height = HEIGHT; \
54 + border_fill_pixmap_background(p, &r, &bg, cd); \
57 static void border_draw_one_border_part(
58 common_decorations_type *cd, FvwmWindow *fw, rectangle *sidebar_g,
59 rectangle *frame_g, border_relief_descr *br, window_parts part,
63 Bool free_bg_pixmap = False;
64 + int x, y, width, height;
67 border_get_part_geometry(fw, part, sidebar_g, &part_g, &w);
68 @@ -1965,8 +1992,28 @@
69 relative_g.height = fw->g.frame.height;
70 relative_g.x = part_g.x;
71 relative_g.y = part_g.y;
72 - border_get_border_background(
73 - &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, part);
76 + FvwmPicture* fp = 0;
77 + df = border_get_border_style(fw, (Scr.Hilite == fw));
78 + if (DFS_FACE_TYPE(df->style) == MultiBorder)
81 + if (part==PART_BORDER_NW) id = 0;
82 + if (part==PART_BORDER_N) id = 1;
83 + if (part==PART_BORDER_NE) id = 2;
84 + if (part==PART_BORDER_E) id = 3;
85 + if (part==PART_BORDER_SE) id = 4;
86 + if (part==PART_BORDER_S) id = 5;
87 + if (part==PART_BORDER_SW) id = 6;
88 + if (part==PART_BORDER_W) id = 7;
90 + if (id>=0 && df->u.mb.pixmaps[id])
92 + fp = df->u.mb.pixmaps[id];
96 if (cd->texture_pixmap)
99 @@ -2009,13 +2056,100 @@
103 - /* set the geometry for drawing the Tiled pixmap; maybe add the relief
107 - pix_g.width = part_g.width;
108 - pix_g.height = part_g.height;
109 - border_fill_pixmap_background(p, &pix_g, &bg, cd);
111 + border_get_border_background(
112 + &bg, cd, &part_g, &relative_g, &free_bg_pixmap, w, PART_NONE, fp);
114 + int px = bg.pixmap.g.x;
115 + int py = bg.pixmap.g.y;
119 + /* Position pixmap so that it's aligned to the edge of the window */
120 + if (part & PART_BOTTOM)
122 + bg.pixmap.g.y = fp->height - sidebar_g->y;
123 + if (part == PART_BORDER_S)
125 + bg.pixmap.g.y = fp->height - fw->boundary_width;
128 + if (part & PART_RIGHT)
130 + bg.pixmap.g.x = fp->width - sidebar_g->x;
131 + if (part == PART_BORDER_E)
133 + bg.pixmap.g.x = fp->width - fw->boundary_width;
138 + /* set the geometry for drawing the Tiled pixmap; maybe add the relief
142 + pix_g.width = part_g.width;
143 + pix_g.height = part_g.height;
145 + border_fill_pixmap_background(p, &pix_g, &bg, cd);
147 + bg.pixmap.g.x = px;
148 + bg.pixmap.g.y = py;
152 + height = pix_g.height;
153 + width = pix_g.width;
157 + /* draw parts from other borders that overflow because of their width/height */
159 + if (part==PART_BORDER_S)
161 + DRAWBORDER(6, pix_g.x - sidebar_g->x, fw->boundary_width - fp->height, fp->width - sidebar_g->x, height);
162 + DRAWBORDER(4, pix_g.width - fp->width + sidebar_g->x, fw->boundary_width - fp->height, fp->width - sidebar_g->x, height);
164 + if (!IS_SHADED(fw))
166 + if (part==PART_BORDER_E)
168 + DRAWBORDER(2, fw->boundary_width - fp->width, pix_g.y - sidebar_g->y, width, fp->height - sidebar_g->y);
169 + DRAWBORDER(4, fw->boundary_width - fp->width, pix_g.height - fp->height + sidebar_g->y, width, fp->height - sidebar_g->y);
171 + if (part==PART_BORDER_W)
173 + DRAWBORDER(0, x, pix_g.y - sidebar_g->y, width, fp->height - sidebar_g->y);
174 + DRAWBORDER(6, x, pix_g.height - fp->height + sidebar_g->y, width, fp->height - sidebar_g->y);
177 + if (part==PART_BORDER_N)
179 + DRAWBORDER(2, pix_g.width - fp->width + sidebar_g->x, y, fp->width - sidebar_g->x, height);
180 + DRAWBORDER(0, pix_g.x - fp->width + sidebar_g->x, y, fp->width - sidebar_g->x, height);
182 + /* Use the top border for the whole height of the titlebar, overflowing to parts of the bottom corners if shaded */
185 + if (part==PART_BORDER_W)
187 + DRAWBORDER(0, 0, -height, width, height);
189 + if (part==PART_BORDER_SW)
191 + DRAWBORDER(0, 0, -height*2, width, height - fw->boundary_width);
193 + if (part==PART_BORDER_E)
195 + DRAWBORDER(2, fw->boundary_width - fp->width, -height, width, height);
197 + if (part==PART_BORDER_SE)
199 + DRAWBORDER(2, width - fp->width, -height*2, width, height - fw->boundary_width);
204 if (HAS_FLUXBOX_HANDLES(fw) && (part & PART_BOTTOM))
206 pix_g.y = part_g.height - fw->boundary_width;
207 @@ -2032,6 +2166,7 @@
208 border_fill_fluxbox_handle(p, &pix_g, cd, !(part & PART_BORDER_S));
212 if (free_bg_pixmap && bg.pixmap.p)
214 XFreePixmap(dpy, bg.pixmap.p);
215 @@ -2086,7 +2221,7 @@
224 @@ -3711,7 +3846,7 @@
225 relative_g.x = button_g->x;
226 relative_g.y = button_g->y;
227 border_get_border_background(
228 - &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w, PART_NONE);
229 + &bg, td->cd, button_g, &relative_g, &free_bg_pixmap, w, PART_NONE, (FvwmPicture *)NULL);
232 /* set the geometry for drawing the Tiled pixmap;
233 @@ -4158,7 +4293,7 @@
234 relative_g.y = td->layout.title_g.y;
235 border_get_border_background(
236 &bg, td->cd, &td->layout.title_g, &relative_g,
237 - &free_bg_pixmap, w, PART_NONE);
238 + &free_bg_pixmap, w, PART_NONE, (FvwmPicture *)NULL);
241 /* set the geometry for drawing the Tiled pixmap;
242 diff -U3 -r fvwm/builtins.c fvwm/builtins.c
243 --- fvwm/builtins.c 2011-12-09 21:00:47.315799724 +0100
244 +++ fvwm/builtins.c 2011-12-09 21:31:27.171864221 +0100
249 +static char *ReadMultiBorderDecor(char *s, DecorFace *df)
251 + FvwmPictureAttributes fpa;
257 + pm = df->u.mb.pixmaps;
258 + df->style.face_type = MultiBorder;
260 + for (x = 0; x < 8; x++)
262 + s = DoPeekToken(s, &token, " ", NULL, NULL);
269 + PDestroyFvwmPicture(dpy, pm[x]);
271 + pm[x] = PCacheFvwmPicture(dpy, Scr.NoFocusWin, NULL,
276 + fvwm_msg(ERR, "ReadMultiBorderDecor",
277 + "Pixmap '%s' could not be loaded",
279 + for(y = 0; y < x; y++)
283 + PDestroyFvwmPicture(dpy, pm[y]);
295 * DestroyFvwmDecor -- frees all memory assocated with an FvwmDecor
296 @@ -1501,6 +1545,14 @@
297 free(df->u.mp.pixels);
301 + for (i = 0; i < 8; i++)
303 + if (df->u.mb.pixmaps[i])
305 + PDestroyFvwmPicture(dpy, df->u.mb.pixmaps[i]);
309 case DefaultVectorButton:
311 @@ -1870,6 +1922,15 @@
315 + else if (strncasecmp(style,"MultiBorder",11)==0)
317 + s = ReadMultiBorderDecor(s, df);
322 + DFS_FACE_TYPE(df->style) = MultiBorder;
324 else if (FMiniIconsSupported &&
325 strncasecmp (style, "MiniIcon", 8) == 0)
327 diff -U3 -r fvwm/menus.c fvwm/menus.c
328 --- fvwm/menus.c 2011-12-09 20:59:40.677503490 +0100
329 +++ fvwm/menus.c 2011-12-09 21:31:27.175197468 +0100
330 @@ -2636,6 +2636,41 @@
334 +#define DRAWMENUBORDER(NUM, XX, YY) XCopyArea(\
335 + dpy, pm[(NUM)]->picture, MR_WINDOW(mr), Scr.TransMaskGC,\
336 + 0, 0, pm[(NUM)]->width, pm[(NUM)]->height, (XX), (YY))
337 +static Bool paint_menu_multipixmap_background(
338 + MenuRoot *mr, XEvent *pevent)
340 + MenuStyle *ms = MR_STYLE(mr);
341 + int width, height, x, y;
342 + int bw = MST_BORDER_WIDTH(mr);
344 + pm = ST_FACE(ms).u.mb.pixmaps;
346 + width = MR_WIDTH(mr);
347 + height = MR_HEIGHT(mr);
349 + FvwmPicture *p = pm[0];
351 + width = MR_WIDTH(mr);
352 + height = MR_HEIGHT(mr);
356 + for (x = 0; x < width; x+=pm[1]->width) DRAWMENUBORDER(1, x, 0);
357 + for (x = 0; x < width; x+=pm[5]->width) DRAWMENUBORDER(5, x, height-pm[5]->height);
358 + for (x = 0; x < height; x+=pm[3]->height) DRAWMENUBORDER(3, width-pm[3]->height, x);
359 + for (x = 0; x < height; x+=pm[7]->height) DRAWMENUBORDER(7, 0, x);
361 + DRAWMENUBORDER(0, 0, 0);
362 + DRAWMENUBORDER(2, width-pm[2]->width, 0);
363 + DRAWMENUBORDER(4, width-pm[4]->width, height-pm[4]->height);
364 + DRAWMENUBORDER(6, 0, height-pm[6]->height);
369 static Bool paint_menu_pixmap_background(
370 MenuRoot *mr, XEvent *pevent)
372 @@ -2738,15 +2773,20 @@
374 /* Only the border was obscured. Redraw it centrally instead of
375 * redrawing several menu items. */
377 - dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
378 - MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
379 - SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
380 - HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
381 - SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
382 + if (ms && ST_FACE(ms).type == MultiPixmapMenu)
385 + paint_menu_multipixmap_background(mr, pevent);
390 + dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
391 + MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
392 + SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
393 + HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
394 + SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
398 MR_IS_PAINTED(mr) = 1;
399 /* paint the menu background */
400 @@ -2811,6 +2851,9 @@
402 do_clear = paint_menu_pixmap_background(mr, pevent);
404 + case MultiPixmapMenu:
405 + do_clear = paint_menu_multipixmap_background(mr, pevent);
407 case TiledPixmapMenu:
408 XSetWindowBackgroundPixmap(
409 dpy, MR_WINDOW(mr), ST_FACE(ms).u.p->picture);
410 @@ -2823,11 +2866,14 @@
413 /* draw the relief */
414 - RelieveRectangle(dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
415 - MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
416 - SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
417 - HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
418 - SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
419 + if (!(ms && ST_FACE(ms).type == MultiPixmapMenu))
421 + RelieveRectangle(dpy, MR_WINDOW(mr), 0, 0, MR_WIDTH(mr) - 1,
422 + MR_HEIGHT(mr) - 1, (Pdepth < 2) ?
423 + SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)) :
424 + HILIGHT_GC(MST_MENU_INACTIVE_GCS(mr)),
425 + SHADOW_GC(MST_MENU_INACTIVE_GCS(mr)), bw);
427 /* paint the menu items */
428 for (mi = MR_FIRST_ITEM(mr); mi != NULL; mi = MI_NEXT_ITEM(mi))
430 diff -U3 -r fvwm/menustyle.c fvwm/menustyle.c
431 --- fvwm/menustyle.c 2011-12-09 20:59:40.677503490 +0100
432 +++ fvwm/menustyle.c 2011-12-09 21:31:27.175197468 +0100
436 FvwmPictureAttributes fpa;
440 s = GetNextToken(s, &style);
441 if (style && strncasecmp(style, "--", 2) == 0)
446 + else if (StrEquals(style,"MultiBorder"))
448 + fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0;
449 + pm = mf->u.mb.pixmaps;
451 + for (x = 0; x < 8; x++)
455 + PDestroyFvwmPicture(dpy, pm[x]);
457 + s = GetNextToken(s, &token);
460 + pm[x] = PCacheFvwmPicture(dpy, Scr.NoFocusWin, NULL, token, fpa);
464 + "menustyle_parse_face", "Pixmap '%s' could not be loaded",
471 + "menustyle_parse_face", "Too few parameters for MultiBorder");
473 + if (!token || !pm[x])
475 + for (y = 0; y < x; y++)
479 + PDestroyFvwmPicture(dpy, pm[y]);
488 + if (mf->type == MultiPixmapMenu)
490 + mf->type = SimpleMenu;
494 + mf->type = MultiPixmapMenu;
501 diff -U3 -r fvwm/menustyle.h fvwm/menustyle.h
502 --- fvwm/menustyle.h 2011-12-09 20:59:40.677503490 +0100
503 +++ fvwm/menustyle.h 2011-12-09 21:31:27.175197468 +0100
510 /* max button is 8 (0x8) */
517 + FvwmPicture *pixmaps[8];
522 diff -U3 -r fvwm/screen.h fvwm/screen.h
523 --- fvwm/screen.h 2011-12-09 21:12:03.205196181 +0100
524 +++ fvwm/screen.h 2011-12-09 21:31:27.175197468 +0100
526 AdjustedPixmapButton,
535 unsigned short solid_flags;
538 + FvwmPicture *pixmaps[8];