1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 #include "FolderP.h"
50 #include <X11/StringDefs.h>
51 #include <Xm/DrawnB.h>
52 #include <Xm/Label.h>
53 #include <Xm/Form.h>
54
55 #include <stdio.h>
56 #include <stdlib.h>
57
58 #ifdef SUNOS4
59 int fprintf(
FILE *,
char *, ...);
60 #endif
61
62
63 static void ClassInitialize();
64 static void Initialize(Widget req, Widget newW,
65 ArgList args, Cardinal *nargs);
66 static void Destroy(Widget w);
67
68
69 static void Realize(Widget w, XtValueMask *valueMask,
70 XSetWindowAttributes *attr);
71 static void Redisplay(Widget w, XExposeEvent *event, Region region);
72 static void Layout(XmLFolderWidget f,
int resizeIfNeeded);
73 static void LayoutTopBottom(XmLFolderWidget f,
int resizeIfNeeded);
74 static void LayoutLeftRight(XmLFolderWidget f,
int resizeIfNeeded);
75 static void Resize(Widget w);
76 static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
77 XtWidgetGeometry *);
78 static void ChangeManaged(Widget w);
79 static void ConstraintInitialize(Widget, Widget w,
80 ArgList args, Cardinal *nargs);
81 static void ConstraintDestroy(Widget w);
82 static void SetActiveTab(XmLFolderWidget f, Widget w, XEvent *event,
83 Boolean notify);
84 static void DrawTabPixmap(XmLFolderWidget f, Widget tab,
int active);
85 static void DrawManagerShadowLeftRight(XmLFolderWidget f, XRectangle *rect);
86 static void DrawManagerShadowTopBottom(XmLFolderWidget f, XRectangle *rect);
87 static void DrawTabHighlight(XmLFolderWidget f, Widget w);
88 static void SetTabPlacement(XmLFolderWidget f, Widget tab);
89 static void GetTabRect(XmLFolderWidget f, Widget tab, XRectangle *rect,
90 int includeShadow);
91 static void DrawTabShadowArcTopBottom(XmLFolderWidget f, Widget w);
92 static void DrawTabShadowArcLeftRight(XmLFolderWidget f, Widget w);
93 static void DrawTabShadowLineTopBottom(XmLFolderWidget f, Widget w);
94 static void DrawTabShadowLineLeftRight(XmLFolderWidget f, Widget w);
95 static void DrawTabShadowNoneTopBottom(XmLFolderWidget f, Widget w);
96 static void DrawTabShadowNoneLeftRight(XmLFolderWidget f, Widget w);
97 static void SetGC(XmLFolderWidget f,
int type);
98
99
100 static Boolean SetValues(Widget curW, Widget reqW, Widget newW,
101 ArgList args, Cardinal *nargs);
102 static Boolean ConstraintSetValues(Widget curW, Widget, Widget newW,
103 ArgList, Cardinal *);
104 static void CopyRenderTable(XmLFolderWidget f);
105 static Boolean CvtStringToCornerStyle(Display *dpy, XrmValuePtr args,
106 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
107 XtPointer *data);
108 static Boolean CvtStringToFolderResizePolicy(Display *dpy, XrmValuePtr args,
109 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
110 XtPointer *data);
111 static Boolean CvtStringToTabPlacement(Display *dpy, XrmValuePtr args,
112 Cardinal *numArgs, XrmValuePtr fromVal, XrmValuePtr toVal,
113 XtPointer *data);
114
115
116 static void GetCoreBackground(Widget w,
int, XrmValue *value);
117 static void GetDefaultTabWidgetClass(Widget w,
int, XrmValue *value);
118 static void GetManagerForeground(Widget w,
int, XrmValue *value);
119 static Boolean ServerDrawsArcsLarge(Display *dpy,
int debug);
120 static void CheckSetRenderTable(Widget wid,
121 int offset,
122 XrmValue *value);
123
124
125 static void Activate(Widget w, XEvent *event, String *, Cardinal *);
126 static void PrimActivate(Widget w, XtPointer, XtPointer);
127 static void PrimFocusIn(Widget w, XEvent *event, String *, Cardinal *);
128 static void PrimFocusOut(Widget w, XEvent *event, String *, Cardinal *);
129
130 static XtActionsRec actions[] =
131 {
132 {
"XmLFolderActivate", Activate },
133 {
"XmLFolderPrimFocusIn", PrimFocusIn },
134 {
"XmLFolderPrimFocusOut", PrimFocusOut },
135 };
136
137 #define MAX_TAB_ROWS 64
138
139 #define GC_SHADOWBOT 0
140 #define GC_SHADOWTOP 1
141 #define GC_BLANK 2
142 #define GC_UNSET 3
143
144
145
146 static char translations[] =
147 "<Btn1Down>: XmLFolderActivate()\n\
148 <EnterWindow>: ManagerEnter()\n\
149 <LeaveWindow>: ManagerLeave()\n\
150 <FocusOut>: ManagerFocusOut()\n\
151 <FocusIn>: ManagerFocusIn()";
152
153
154
155 static char primTranslations[] =
156 "<FocusIn>: XmLFolderPrimFocusIn() PrimitiveFocusIn()\n\
157 <FocusOut>: XmLFolderPrimFocusOut() PrimitiveFocusOut()";
158
159 static XtResource resources[] =
160 {
161
162 {
163 XmNtabWidgetClass, XmCTabWidgetClass,
164 XmRWidgetClass,
sizeof(WidgetClass),
165 XtOffset(XmLFolderWidget, folder.tabWidgetClass),
166 XmRCallProc, (XtPointer)GetDefaultTabWidgetClass,
167 },
168 {
169 XmNactivateCallback, XmCCallback,
170 XmRCallback,
sizeof(XtCallbackList),
171 XtOffset(XmLFolderWidget, folder.activateCallback),
172 XmRImmediate, (XtPointer)
0,
173 },
174 {
175 XmNactiveTab, XmCActiveTab,
176 XmRInt,
sizeof(
int),
177 XtOffset(XmLFolderWidget, folder.activeTab),
178 XmRImmediate, (XtPointer)-
1,
179 },
180 {
181 XmNautoSelect, XmCAutoSelect,
182 XmRBoolean,
sizeof(Boolean),
183 XtOffset(XmLFolderWidget, folder.autoSelect),
184 XmRImmediate, (XtPointer)True,
185 },
186 {
187 XmNblankBackground, XmCBlankBackground,
188 XmRPixel,
sizeof(Pixel),
189 XtOffset(XmLFolderWidget, folder.blankBg),
190 XmRCallProc, (XtPointer)GetCoreBackground,
191 },
192 {
193 XmNblankBackgroundPixmap, XmCBlankBackgroundPixmap,
194 XmRManForegroundPixmap,
sizeof(Pixmap),
195 XtOffset(XmLFolderWidget, folder.blankPix),
196 XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
197 },
198 {
199 XmNcornerDimension, XmCCornerDimension,
200 XmRDimension,
sizeof(Dimension),
201 XtOffset(XmLFolderWidget, folder.cornerDimension),
202 XmRImmediate, (XtPointer)
2,
203 },
204 {
205 XmNcornerStyle, XmCCornerStyle,
206 XmRCornerStyle,
sizeof(
unsigned char),
207 XtOffset(XmLFolderWidget, folder.cornerStyle),
208 XmRImmediate, (XtPointer)XmCORNER_ARC,
209 },
210 {
211 "pri.vate",
"Pri.vate",XmRBoolean,
212 sizeof(Boolean), XtOffset(XmLFolderWidget, folder.check_set_render_table),
213 XmRImmediate, (XtPointer) False
214 },
215 {
216 XmNfontList, XmCFontList,
217 XmRFontList,
sizeof(XmFontList),
218 XtOffset(XmLFolderWidget, folder.renderTable),
219 XmRCallProc, (XtPointer)CheckSetRenderTable,
220 },
221 {
222 XmNrenderTable, XmCRenderTable,
223 XmRRenderTable,
sizeof(XmRenderTable),
224 XtOffset(XmLFolderWidget, folder.renderTable),
225 XmRCallProc, (XtPointer)CheckSetRenderTable,
226 },
227 {
228 XmNhighlightThickness, XmCHighlightThickness,
229 XmRDimension,
sizeof(Dimension),
230 XtOffset(XmLFolderWidget, folder.highlightThickness),
231 XmRImmediate, (XtPointer)
2,
232 },
233 {
234 XmNinactiveBackground, XmCInactiveBackground,
235 XmRPixel,
sizeof(Pixel),
236 XtOffset(XmLFolderWidget, folder.inactiveBg),
237 XmRCallProc, (XtPointer)GetCoreBackground,
238 },
239 {
240 XmNinactiveForeground, XmCInactiveForeground,
241 XmRPixel,
sizeof(Pixel),
242 XtOffset(XmLFolderWidget, folder.inactiveFg),
243 XmRCallProc, (XtPointer)GetManagerForeground,
244 },
245 {
246 XmNmarginHeight, XmCMarginHeight,
247 XmRDimension,
sizeof(Dimension),
248 XtOffset(XmLFolderWidget, folder.marginHeight),
249 XmRImmediate, (XtPointer)
0,
250 },
251 {
252 XmNmarginWidth, XmCMarginWidth,
253 XmRDimension,
sizeof(Dimension),
254 XtOffset(XmLFolderWidget, folder.marginWidth),
255 XmRImmediate, (XtPointer)
0,
256 },
257 {
258 XmNminTabWidth, XmCminTabWidth,
259 XmRDimension,
sizeof(Dimension),
260 XtOffset(XmLFolderWidget, folder.minTabWidth),
261 XmRImmediate, (XtPointer)
0,
262 },
263 {
264 XmNmaxTabWidth, XmCmaxTabWidth,
265 XmRDimension,
sizeof(Dimension),
266 XtOffset(XmLFolderWidget, folder.maxTabWidth),
267 XmRImmediate, (XtPointer)
100,
268 },
269 {
270 XmNpixmapMargin, XmCPixmapMargin,
271 XmRDimension,
sizeof(Dimension),
272 XtOffset(XmLFolderWidget, folder.pixmapMargin),
273 XmRImmediate, (XtPointer)
2,
274 },
275 {
276 XmNresizePolicy, XmCFolderResizePolicy,
277 XmRFolderResizePolicy,
sizeof(
unsigned char),
278 XtOffset(XmLFolderWidget, folder.resizePolicy),
279 XmRImmediate, (XtPointer)XmRESIZE_STATIC,
280 },
281 {
282 XmNrotateWhenLeftRight, XmCRotateWhenLeftRight,
283 XmRBoolean,
sizeof(Boolean),
284 XtOffset(XmLFolderWidget, folder.allowRotate),
285 XmRImmediate, (XtPointer)True,
286 },
287 {
288 XmNspacing, XmCSpacing,
289 XmRDimension,
sizeof(Dimension),
290 XtOffset(XmLFolderWidget, folder.spacing),
291 XmRImmediate, (XtPointer)
0,
292 },
293 {
294 XmNtabBarHeight, XmCTabBarHeight,
295 XmRDimension,
sizeof(Dimension),
296 XtOffset(XmLFolderWidget, folder.tabBarHeight),
297 XmRImmediate, (XtPointer)
0,
298 },
299 {
300 XmNtabCount, XmCTabCount,
301 XmRInt,
sizeof(
int),
302 XtOffset(XmLFolderWidget, folder.tabCount),
303 XmRImmediate, (XtPointer)
0,
304 },
305 {
306 XmNtabPlacement, XmCTabPlacement,
307 XmRTabPlacement,
sizeof(
unsigned char),
308 XtOffset(XmLFolderWidget, folder.tabPlacement),
309 XmRImmediate, (XtPointer)XmFOLDER_TOP,
310 },
311 {
312 XmNtabsPerRow, XmCTabsPerRow,
313 XmRInt,
sizeof(
int),
314 XtOffset(XmLFolderWidget, folder.tabsPerRow),
315 XmRImmediate, (XtPointer)
0,
316 },
317 {
318 XmNtabWidgetList, XmCReadOnly,
319 XmRPointer,
sizeof(XtPointer),
320 XtOffset(XmLFolderWidget, folder.tabs),
321 XmRImmediate, (XtPointer)
0,
322 },
323 {
324 XmNtabTranslations, XmCTranslations,
325 XmRTranslationTable,
sizeof(XtTranslations),
326 XtOffset(XmLFolderWidget, folder.primTrans),
327 XmRString, (XtPointer)primTranslations,
328 },
329 {
330 XmNdebugLevel, XmCDebugLevel,
331 XmRInt,
sizeof(
int),
332 XtOffset(XmLFolderWidget, folder.debugLevel),
333 XmRImmediate, (XtPointer)
0,
334 },
335
336 {
337 XmNshadowThickness, XmCShadowThickness,
338 XmRHorizontalDimension,
sizeof(Dimension),
339 XtOffset(XmLFolderWidget, manager.shadow_thickness),
340 XmRImmediate, (XtPointer)
2,
341 },
342 };
343
344 static XtResource constraint_resources[] =
345 {
346
347 {
348 XmNtabFreePixmaps, XmCTabFreePixmaps,
349 XmRBoolean,
sizeof(Boolean),
350 XtOffset(XmLFolderConstraintPtr, folder.freePix),
351 XmRImmediate, (XtPointer)False,
352 },
353 {
354 XmNtabInactivePixmap, XmCTabInactivePixmap,
355 XmRPrimForegroundPixmap,
sizeof(Pixmap),
356 XtOffset(XmLFolderConstraintPtr, folder.inactPix),
357 XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
358 },
359 {
360 XmNtabManagedName, XmCTabManagedName,
361 XmRString,
sizeof(
char *),
362 XtOffset(XmLFolderConstraintPtr, folder.managedName),
363 XmRImmediate, (XtPointer)
0,
364 },
365 {
366 XmNtabManagedWidget, XmCTabManagedWidget,
367 XmRWidget,
sizeof(Widget),
368 XtOffset(XmLFolderConstraintPtr, folder.managedW),
369 XmRImmediate, (XtPointer)
0,
370 },
371 {
372 XmNtabPixmap, XmCTabPixmap,
373 XmRPrimForegroundPixmap,
sizeof(Pixmap),
374 XtOffset(XmLFolderConstraintPtr, folder.pix),
375 XmRImmediate, (XtPointer)XmUNSPECIFIED_PIXMAP,
376 },
377 };
378
379 XmLFolderClassRec xmlFolderClassRec =
380 {
381 {
382 (WidgetClass)&xmManagerClassRec,
383 "XmLFolder",
384 sizeof(XmLFolderRec),
385 ClassInitialize,
386 0,
387 FALSE,
388 (XtInitProc)Initialize,
389 0,
390 (XtRealizeProc)Realize,
391 (XtActionList)actions,
392 (Cardinal)XtNumber(actions),
393 (XtResource *)resources,
394 XtNumber(resources),
395 NULLQUARK,
396 TRUE,
397 XtExposeCompressMultiple,
398 TRUE,
399 TRUE,
400 (XtWidgetProc)Destroy,
401 (XtWidgetProc)Resize,
402 (XtExposeProc)Redisplay,
403 (XtSetValuesFunc)SetValues,
404 0,
405 XtInheritSetValuesAlmost,
406 0,
407 0,
408 XtVersion,
409 0,
410 translations,
411 0,
412 0,
413 0,
414 },
415 {
416 (XtGeometryHandler)GeometryManager,
417 (XtWidgetProc)ChangeManaged,
418 XtInheritInsertChild,
419 XtInheritDeleteChild,
420 0,
421 },
422 {
423 (XtResource *)constraint_resources,
424 XtNumber(constraint_resources),
425 sizeof(XmLFolderConstraintRec),
426 (XtInitProc)ConstraintInitialize,
427 (XtWidgetProc)ConstraintDestroy,
428 (XtSetValuesFunc)ConstraintSetValues,
429 0,
430 },
431 {
432 XtInheritTranslations,
433 0,
434 0,
435 0,
436 0,
437 XmInheritParentProcess,
438 0,
439 },
440 {
441 0,
442 }
443 };
444
445 WidgetClass xmlFolderWidgetClass = (WidgetClass)&xmlFolderClassRec;
446
447
448
449 static void
450 CheckSetRenderTable(Widget wid,
451 int offset,
452 XrmValue *value)
453 {
454 XmLFolderWidget lw = (XmLFolderWidget)wid;
455
456
457 if (lw->folder.check_set_render_table)
458 value->addr =
NULL;
459 else {
460 lw->folder.check_set_render_table = True;
461 value->addr = (
char*)&(lw->folder.renderTable);
462 }
463
464 }
465
466
467
468
469 static void
470 ClassInitialize(
void)
471 {
472 XmLInitialize();
473
474 XtSetTypeConverter(XmRString, XmRCornerStyle,
475 CvtStringToCornerStyle,
0,
0, XtCacheNone,
0);
476 XtSetTypeConverter(XmRString, XmRFolderResizePolicy,
477 CvtStringToFolderResizePolicy,
0,
0, XtCacheNone,
0);
478 XtSetTypeConverter(XmRString, XmRTabPlacement,
479 CvtStringToTabPlacement,
0,
0, XtCacheNone,
0);
480 }
481
482 static void
483 Initialize(Widget req,
484 Widget newW,
485 ArgList args,
486 Cardinal *narg)
487 {
488 Display *dpy;
489
490 XmLFolderWidget f;
491
492 f = (XmLFolderWidget)newW;
493 dpy = XtDisplay((Widget)f);
494
495 if (f->core.width ==
0)
496 f->core.width =
100;
497 if (f->core.height ==
0)
498 f->core.height =
100;
499
500 f->folder.gc =
0;
501
502 f->folder.tabAllocCount =
32;
503 f->folder.tabs = (Widget *)malloc(
sizeof(Widget) *
32);
504 f->folder.tabHeight =
0;
505 f->folder.tabWidth =
0;
506 f->folder.activeW =
0;
507 f->folder.focusW =
0;
508 f->folder.allowLayout =
1;
509 f->folder.activeRow = -
1;
510 CopyRenderTable(f);
511
512 if (f->folder.tabBarHeight)
513 {
514 XmLWarning((Widget)f,
"Initialize() - can''t set tabBarHeight");
515 f->folder.tabBarHeight =
0;
516 }
517 if (f->folder.tabCount)
518 {
519 XmLWarning((Widget)f,
"Initialize() - can''t set tabCount");
520 f->folder.tabCount =
0;
521 }
522 if (f->folder.activeTab != -
1)
523 {
524 XmLWarning((Widget)f,
"Initialize() - can''t set activeTab");
525 f->folder.activeTab = -
1;
526 }
527 if (f->folder.cornerDimension <
1)
528 {
529 XmLWarning((Widget)f,
"Initialize() - cornerDimension can''t be < 1");
530 f->folder.cornerDimension =
1;
531 }
532 f->folder.serverDrawsArcsLarge = ServerDrawsArcsLarge(dpy,
533 f->folder.debugLevel);
534 if (f->folder.minTabWidth <=
0)
535 {
536
537
538 XmString st = XmStringCreateSimple(
"W");
539 f->folder.minTabWidth = XmStringWidth(f->folder.renderTable, st);
540 XmStringFree(st);
541 }
542 }
543
544 static void
545 Destroy(Widget w)
546 {
547 XmLFolderWidget f;
548 Display *dpy;
549
550 f = (XmLFolderWidget)w;
551 dpy = XtDisplay(w);
552 if (f->folder.debugLevel)
553 fprintf(stderr,
"Folder destroy: \n");
554 if (f->folder.tabs)
555 free((
char *)f->folder.tabs);
556 if (f->folder.gc)
557 XFreeGC(dpy, f->folder.gc);
558 XmRenderTableFree(f->folder.renderTable);
559 }
560
561
562
563
564
565 static void
566 Realize(Widget w,
567 XtValueMask *valueMask,
568 XSetWindowAttributes *attr)
569 {
570 XmLFolderWidget f;
571 Display *dpy;
572 WidgetClass superClass;
573 XtRealizeProc realize;
574 XGCValues values;
575 XtGCMask mask;
576
577 f = (XmLFolderWidget)w;
578 dpy = XtDisplay(f);
579 superClass = xmlFolderWidgetClass->core_class.superclass;
580 realize = superClass->core_class.realize;
581 (*realize)(w, valueMask, attr);
582
583 if (!f->folder.gc)
584 {
585 values.foreground = f->manager.foreground;
586 mask = GCForeground;
587 f->folder.gc = XCreateGC(dpy, XtWindow(f), mask, &values);
588 if (f->folder.autoSelect == True && f->folder.tabCount)
589 XmLFolderSetActiveTab(w,
0, False);
590 }
591 }
592
593 static void
594 Redisplay(Widget w,
595 XExposeEvent *event,
596 Region region)
597 {
598 Display *dpy;
599 Window win;
600 XmLFolderWidget f;
601 XmLFolderConstraintRec *fc;
602 XRectangle eRect, rRect, rect;
603
604
605 Widget tab;
606 int i;
607
608 f = (XmLFolderWidget)w;
609 if (!XtIsRealized(w))
610 return;
611 if (!f->core.visible)
612 return;
613 dpy = XtDisplay(f);
614 win = XtWindow(f);
615
616 if (event)
617 {
618 eRect.x = event->x;
619 eRect.y = event->y;
620 eRect.width = event->width;
621 eRect.height = event->height;
622 if (f->folder.debugLevel >
1)
623 fprintf(stderr,
"XmLFolder: Redisplay x %d y %d w %d h %d\n",
624 event->x, event->y, event->width, event->height);
625 }
626 else
627 {
628 eRect.x =
0;
629 eRect.y =
0;
630 eRect.width = f->core.width;
631 eRect.height = f->core.height;
632 }
633 if (!eRect.width || !eRect.height)
634 return;
635
636 if (f->folder.tabPlacement == XmFOLDER_TOP)
637 {
638 rRect.x =
0;
639 rRect.y = f->folder.tabHeight;
640 rRect.width = f->core.width;
641 rRect.height = f->core.height - f->folder.tabHeight;
642 }
643 else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
644 {
645 rRect.x =
0;
646 rRect.y =
0;
647 rRect.width = f->core.width;
648 rRect.height = f->core.height - f->folder.tabHeight;
649 }
650 if (f->folder.tabPlacement == XmFOLDER_LEFT)
651 {
652 rRect.x = f->folder.tabWidth;
653 rRect.y =
0;
654 rRect.width = f->core.width - f->folder.tabWidth;
655 rRect.height = f->core.height;
656 }
657 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
658 {
659 rRect.x =
0;
660 rRect.y =
0;
661 rRect.width = f->core.width - f->folder.tabWidth;
662 rRect.height = f->core.height;
663 }
664 if (XmLRectIntersect(&eRect, &rRect) != XmLRectOutside)
665 {
666 if (f->folder.tabPlacement == XmFOLDER_TOP ||
667 f->folder.tabPlacement == XmFOLDER_BOTTOM)
668 DrawManagerShadowTopBottom(f, &rRect);
669 else
670 DrawManagerShadowLeftRight(f, &rRect);
671 }
672
673 if (!f->folder.tabCount)
674 return;
675
676 rRect.x =
0;
677 rRect.y =
0;
678 rRect.width =
0;
679 rRect.height =
0;
680
681
682 for (i =
0; i < f->folder.tabCount; i++)
683 {
684 tab = f->folder.tabs[i];
685 if (!XtIsManaged(tab))
686 continue;
687 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
688 GetTabRect(f, tab, &rRect,
0);
689
690
691 rect = rRect;
692 if (f->folder.tabPlacement == XmFOLDER_TOP ||
693 f->folder.tabPlacement == XmFOLDER_BOTTOM)
694 rect.width += f->folder.spacing;
695 else
696 rect.height += f->folder.spacing;
697
698
699 if (f->folder.tabsPerRow)
700 {
701 if (rRect.x ==
2)
702 rect.x =
0;
703 if (rRect.y ==
2)
704 rect.y =
0;
705 if (rRect.x + rRect.width == f->core.width -
2)
706 rect.width +=
2;
707 if (rRect.y + rRect.height == f->core.height -
2)
708 rect.height +=
2;
709 }
710
711 if (XmLRectIntersect(&eRect, &rect) == XmLRectOutside)
712 continue;
713 if (event && XRectInRegion(region, rect.x, rect.y,
714 rect.width, rect.height) == RectangleOut)
715 continue;
716
717 if (f->folder.debugLevel >
1)
718 fprintf(stderr,
"XmLFolder: Redisplay tab for widget %d\n", i);
719 if (tab == f->folder.activeW)
720 {
721 XtVaSetValues(tab,
722 XmNbackground, f->core.background_pixel,
723 XmNforeground, f->manager.foreground,
724 NULL);
725 }
726 else
727 {
728 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
729 XFillRectangle(dpy, win, f->folder.gc,
730 rRect.x, rRect.y, rRect.width, rRect.height);
731 XtVaSetValues(tab,
732 XmNbackground, f->folder.inactiveBg,
733 XmNforeground, f->folder.inactiveFg,
734 NULL);
735 }
736
737 if (f->folder.tabPlacement == XmFOLDER_TOP ||
738 f->folder.tabPlacement == XmFOLDER_BOTTOM)
739 {
740 if (f->folder.cornerStyle == XmCORNER_LINE)
741 DrawTabShadowLineTopBottom(f, tab);
742 else if (f->folder.cornerStyle == XmCORNER_ARC)
743 DrawTabShadowArcTopBottom(f, tab);
744 else
745 DrawTabShadowNoneTopBottom(f, tab);
746 }
747 else
748 {
749 if (f->folder.cornerStyle == XmCORNER_LINE)
750 DrawTabShadowLineLeftRight(f, tab);
751 else if (f->folder.cornerStyle == XmCORNER_ARC)
752 DrawTabShadowArcLeftRight(f, tab);
753 else
754 DrawTabShadowNoneLeftRight(f, tab);
755 }
756
757 if (f->folder.focusW == tab)
758 DrawTabHighlight(f, tab);
759
760 if (tab == f->folder.activeW &&
761 fc->folder.pix != XmUNSPECIFIED_PIXMAP &&
762 (fc->folder.maxPixWidth || fc->folder.maxPixHeight))
763 DrawTabPixmap(f, tab,
1);
764 else if (tab != f->folder.activeW &&
765 fc->folder.inactPix != XmUNSPECIFIED_PIXMAP &&
766 (fc->folder.maxPixWidth || fc->folder.maxPixHeight))
767 DrawTabPixmap(f, tab,
0);
768
769 SetGC(f,
GC_BLANK);
770
771
772 if (f->folder.tabsPerRow)
773 {
774 if (rRect.x ==
2)
775 {
776 rect = rRect;
777 rect.x =
0;
778 rect.width =
2;
779 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
780 rect.width, rect.height);
781 }
782 if (rRect.y ==
2)
783 {
784 rect = rRect;
785 rect.y =
0;
786 rect.height =
2;
787 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
788 rect.width, rect.height);
789 }
790 if (rRect.x + rRect.width == f->core.width -
2)
791 {
792 rect = rRect;
793 rect.x = f->core.width -
2;
794 rect.width =
2;
795 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
796 rect.width, rect.height);
797 }
798 if (rRect.y + rRect.height == f->core.height -
2)
799 {
800 rect = rRect;
801 rect.y = f->core.height -
2;
802 rect.height =
2;
803 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
804 rect.width, rect.height);
805 }
806 }
807
808 if (f->folder.spacing)
809 {
810 if (f->folder.tabPlacement == XmFOLDER_TOP ||
811 f->folder.tabPlacement == XmFOLDER_BOTTOM)
812 XFillRectangle(dpy, win, f->folder.gc, rRect.x + rRect.width,
813 rRect.y, f->folder.spacing, rRect.height);
814 else
815 XFillRectangle(dpy, win, f->folder.gc, rRect.x,
816 rRect.y + rRect.height, rRect.width, f->folder.spacing);
817 }
818
819 SetGC(f,
GC_UNSET);
820 }
821
822
823 if (!f->folder.tabsPerRow)
824 {
825 if (f->folder.tabPlacement == XmFOLDER_TOP ||
826 f->folder.tabPlacement == XmFOLDER_BOTTOM)
827 {
828 rRect.x += rRect.width + f->folder.spacing;
829 if ((
int)f->core.width > rRect.x)
830 {
831 if (f->folder.tabPlacement == XmFOLDER_TOP)
832 rRect.y =
0;
833 else
834 rRect.y = f->core.height - f->folder.tabHeight;
835 rRect.width = f->core.width - rRect.x;
836 rRect.height = f->folder.tabHeight;
837 SetGC(f,
GC_BLANK);
838 XFillRectangle(dpy, win, f->folder.gc,
839 rRect.x, rRect.y, rRect.width, rRect.height);
840 SetGC(f,
GC_UNSET);
841 }
842 }
843 else
844 {
845 rRect.y += rRect.height + f->folder.spacing;
846 if ((
int)f->core.height > rRect.y)
847 {
848 if (f->folder.tabPlacement == XmFOLDER_LEFT)
849 rRect.x =
0;
850 else
851 rRect.x = f->core.width - f->folder.tabWidth;
852 rRect.width = f->folder.tabWidth;
853 rRect.height = f->core.height - rRect.y;
854 SetGC(f,
GC_BLANK);
855 XFillRectangle(dpy, win, f->folder.gc,
856 rRect.x, rRect.y, rRect.width, rRect.height);
857 SetGC(f,
GC_UNSET);
858 }
859 }
860 }
861 }
862
863 static void
864 Layout(XmLFolderWidget f,
865 int resizeIfNeeded)
866 {
867
868
869 if (!f->folder.allowLayout)
870 return;
871 f->folder.allowLayout =
0;
872 if (f->folder.tabPlacement == XmFOLDER_LEFT ||
873 f->folder.tabPlacement == XmFOLDER_RIGHT)
874 LayoutLeftRight(f, resizeIfNeeded);
875 else
876 LayoutTopBottom(f, resizeIfNeeded);
877 if (XtIsRealized((Widget)f) && f->core.visible)
878 XClearArea(XtDisplay(f), XtWindow(f),
0,
0,
0,
0, True);
879 f->folder.allowLayout =
1;
880 }
881
882 static void
883 LayoutTopBottom(XmLFolderWidget f,
884 int resizeIfNeeded)
885 {
886 Display *dpy;
887 Window root;
888 int i, tabNum, x, y, w, h, pad1, pad2;
889 int rowNum, numRows, rowHeight, rowX, rowY;
890 WidgetList children;
891 Widget tab, child;
892 XmLFolderConstraintRec *fc;
893 XtGeometryResult result;
894 unsigned int inactPixHeight, pixHeight;
895 unsigned int inactPixWidth, pixWidth;
896 unsigned int pixBW, pixDepth;
897 Dimension height, minHeight;
898 Dimension width, minWidth, borderWidth;
899 Dimension co;
900 int st, ht;
901 int tabFit =
0, tgtTabWidth =
0;
902 int tabPaddingWidth, tailSpace =
0;
903 Boolean map, isManaged;
904 struct
905 {
906 int width, height, numTabs, y;
907 } rows[
MAX_TAB_ROWS];
908
909 dpy = XtDisplay(f);
910 children = f->composite.children;
911 st = f->manager.shadow_thickness;
912 ht = f->folder.highlightThickness;
913
914
915 if (f->folder.cornerStyle == XmCORNER_LINE)
916 co = (Dimension)((
double)f->folder.cornerDimension * .
5 + .
99);
917 else if (f->folder.cornerStyle == XmCORNER_ARC)
918 co = (Dimension)((
double)f->folder.cornerDimension * .
3 + .
99);
919 else
920 co =
0;
921
922
923
924 rowX =
0;
925 rowY =
0;
926 rowHeight =
0;
927 rowNum =
0;
928 tabNum =
0;
929 minWidth =
0;
930
931 if (f->folder.tabCount && f->folder.resizePolicy == XmRESIZE_PACK)
932 {
933 int maxTabWidth = f->folder.maxTabWidth;
934 int tabEffCount =
0;
935
936 for (i =
0; i < f->folder.tabCount; i++)
937 {
938 tab = f->folder.tabs[i];
939 if (!XtIsManaged(tab))
940 continue;
941 tabEffCount++;
942 }
943
944 tabPaddingWidth = (st + co + f->folder.marginWidth + ht +
945 f->folder.tabs[
0]->core.border_width) *
2;
946 if (maxTabWidth * tabEffCount > f->core.width)
947 {
948 tgtTabWidth = f->core.width/tabEffCount - tabPaddingWidth;
949 tailSpace = f->core.width % tabEffCount;
950 tabFit =
1;
951
952
953 if (tgtTabWidth < f->folder.minTabWidth) {
954 tgtTabWidth = f->folder.minTabWidth;
955 tabFit =
0;
956 }
957 }
958 else
959 {
960 tgtTabWidth = maxTabWidth - tabPaddingWidth;
961 tabFit =
0;
962 }
963 }
964
965 for (i =
0; i < f->folder.tabCount; i++)
966 {
967 tab = f->folder.tabs[i];
968 if (!XtIsManaged(tab))
969 continue;
970
971 if (f->folder.resizePolicy == XmRESIZE_PACK)
972 {
973 if (tabFit)
974 {
975 XtVaSetValues(tab, XmNwidth,
976 tailSpace? tgtTabWidth+
1: tgtTabWidth,
NULL);
977 if (tailSpace)
978 tailSpace--;
979 }
980 else
981 {
982 XtVaSetValues(tab, XmNwidth, tgtTabWidth,
NULL);
983 }
984 }
985
986 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
987
988
989 fc->folder.firstInRow = False;
990 if (!tabNum)
991 fc->folder.firstInRow = True;
992 if (f->folder.tabsPerRow && tabNum == f->folder.tabsPerRow)
993 {
994 fc->folder.firstInRow = True;
995
996
997 if (rowX)
998 rowX -= f->folder.spacing;
999 rows[rowNum].y = rowY;
1000 rows[rowNum].width = rowX;
1001 rows[rowNum].height = rowHeight;
1002 rows[rowNum].numTabs = tabNum;
1003 if (f->folder.debugLevel)
1004 {
1005 fprintf(stderr,
"XmLFolder: Layout: ");
1006 fprintf(stderr,
"row %d: y %d w %d h %d numTabs %d\n",
1007 rowNum, rowY, rowX, rowHeight, tabNum);
1008 }
1009 rowY += rowHeight;
1010 rowHeight =
0;
1011 if (rowX > (
int)minWidth)
1012 minWidth = rowX;
1013 rowX =
0;
1014 tabNum =
0;
1015 rowNum++;
1016 if (rowNum ==
MAX_TAB_ROWS -
1)
1017 {
1018 XmLWarning((Widget)f,
"Layout ERROR - too many rows\n");
1019 return;
1020 }
1021 }
1022
1023
1024 height = co + st + tab->core.height + tab->core.border_width *
2 +
1025 f->folder.marginHeight *
2 + ht *
2;
1026 if ((
int)height > rowHeight)
1027 rowHeight = height;
1028
1029
1030 fc->folder.pixWidth =
0;
1031 fc->folder.pixHeight =
0;
1032 fc->folder.inactPixWidth =
0;
1033 fc->folder.inactPixHeight =
0;
1034 fc->folder.maxPixWidth =
0;
1035 fc->folder.maxPixHeight =
0;
1036 if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
1037 {
1038 XGetGeometry(dpy, fc->folder.pix, &root,
1039 &x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
1040 fc->folder.pixWidth = pixWidth;
1041 fc->folder.maxPixWidth = pixWidth;
1042 fc->folder.pixHeight = pixHeight;
1043 fc->folder.maxPixHeight = pixHeight;
1044 height = co + st + pixHeight + f->folder.marginHeight *
2 + ht *
2;
1045 if ((
int)height > rowHeight)
1046 rowHeight = height;
1047 }
1048 if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
1049 {
1050 XGetGeometry(dpy, fc->folder.inactPix, &root, &x, &y,
1051 &inactPixWidth, &inactPixHeight, &pixBW, &pixDepth);
1052 fc->folder.inactPixWidth = inactPixWidth;
1053 if (inactPixWidth > fc->folder.maxPixWidth)
1054 fc->folder.maxPixWidth = inactPixWidth;
1055 fc->folder.inactPixHeight = inactPixHeight;
1056 if (inactPixHeight > fc->folder.maxPixHeight)
1057 fc->folder.maxPixHeight = inactPixHeight;
1058 height = co + st + inactPixHeight +
1059 f->folder.marginHeight *
2 + ht *
2;
1060 if ((
int)height > rowHeight)
1061 rowHeight = height;
1062 }
1063
1064
1065 rowX += st *
2 + co *
2 + f->folder.marginWidth *
2 + ht *
2 +
1066 XtWidth(tab) + tab->core.border_width *
2;
1067 if (fc->folder.maxPixWidth)
1068 rowX += fc->folder.maxPixWidth + f->folder.pixmapMargin;
1069 rowX += f->folder.spacing;
1070
1071 tabNum++;
1072 fc->folder.row = rowNum;
1073 }
1074
1075
1076 if (rowX)
1077 rowX -= f->folder.spacing;
1078 rows[rowNum].y = rowY;
1079 rows[rowNum].width = rowX;
1080 rows[rowNum].height = rowHeight;
1081 rows[rowNum].numTabs = tabNum;
1082 numRows = rowNum +
1;
1083 if (f->folder.debugLevel)
1084 {
1085 fprintf(stderr,
"XmLFolder: Layout: ");
1086 fprintf(stderr,
"row %d: y %d w %d h %d numTabs %d\n",
1087 rowNum, rowY, rowX, rowHeight, tabNum);
1088 }
1089 f->folder.tabHeight = rowY + rowHeight;
1090 f->folder.tabBarHeight = f->folder.tabHeight;
1091 minHeight = f->folder.tabHeight;
1092 if ((
int)minWidth < rowX)
1093 minWidth = rowX;
1094
1095
1096 if (f->folder.tabsPerRow && minWidth)
1097 minWidth +=
4;
1098
1099 if (f->folder.debugLevel)
1100 {
1101 fprintf(stderr,
"XmLFolder: Layout: ");
1102 fprintf(stderr,
"tab bar minimum w %d h %d\n",
1103 (
int)minWidth, (
int)minHeight);
1104 }
1105
1106
1107
1108 for (i =
0; i < f->composite.num_children; i++)
1109 {
1110 child = children[i];
1111 if (XtIsSubclass(child, xmPrimitiveWidgetClass))
1112 continue;
1113
1114 height = XtHeight(child) + f->folder.tabHeight + st *
2;
1115 if (XtIsWidget(child))
1116 height += child->core.border_width *
2;
1117 if (height > minHeight)
1118 minHeight = height;
1119
1120 width = XtWidth(child) + st *
2;
1121 if (XtIsWidget(child))
1122 width += child->core.border_width *
2;
1123 if (width > minWidth)
1124 minWidth = width;
1125 }
1126
1127 if (f->folder.debugLevel)
1128 {
1129 fprintf(stderr,
"XmLFolder: Layout: ");
1130 fprintf(stderr,
"with non-tabs minimum w %d h %d\n",
1131 (
int)minWidth, (
int)minHeight);
1132 }
1133
1134
1135 if (resizeIfNeeded && f->folder.resizePolicy != XmRESIZE_NONE)
1136 {
1137 if (minWidth <=
0)
1138 minWidth =
1;
1139 if (minHeight <=
0)
1140 minHeight =
1;
1141 result = XtMakeResizeRequest((Widget)f, minWidth, minHeight,
1142 &width, &height);
1143 if (result == XtGeometryAlmost)
1144 XtMakeResizeRequest((Widget)f, width, height,
NULL,
NULL);
1145 }
1146
1147
1148 tab = f->folder.activeW;
1149 if (tab)
1150 {
1151 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
1152 rowNum = fc->folder.row;
1153 f->folder.activeRow = rowNum;
1154 rows[rowNum].y = f->folder.tabHeight - rows[rowNum].height;
1155 for (i = rowNum +
1; i < numRows; i++)
1156 rows[i].y -= rows[rowNum].height;
1157 }
1158 else
1159 f->folder.activeRow = -
1;
1160
1161
1162 for (i =
0; i < f->folder.tabCount; i++)
1163 {
1164 tab = f->folder.tabs[i];
1165 if (!XtIsManaged(tab))
1166 continue;
1167 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
1168 rowNum = fc->folder.row;
1169
1170
1171 if (fc->folder.firstInRow == True)
1172 {
1173 if (f->folder.tabsPerRow && rowNum != f->folder.activeRow)
1174 x =
2;
1175 else
1176 x =
0;
1177 }
1178 fc->folder.x = x;
1179 x += st + co + f->folder.marginWidth + ht;
1180 if (fc->folder.maxPixWidth)
1181 x += fc->folder.maxPixWidth + f->folder.pixmapMargin;
1182
1183
1184 fc->folder.height = rows[rowNum].height;
1185 if (f->folder.tabPlacement == XmFOLDER_TOP)
1186 {
1187 fc->folder.y = rows[rowNum].y;
1188 y = fc->folder.y + fc->folder.height - f->folder.marginHeight -
1189 ht - XtHeight(tab) - tab->core.border_width *
2;
1190 }
1191 else
1192 {
1193 fc->folder.y = f->core.height - rows[rowNum].y -
1194 rows[rowNum].height;
1195 y = fc->folder.y + f->folder.marginHeight + ht;
1196 }
1197
1198
1199 pad1 =
0;
1200 pad2 =
0;
1201 w = f->core.width - rows[rowNum].width;
1202 if (rowNum != f->folder.activeRow)
1203 w -=
4;
1204 if (f->folder.tabsPerRow && w >
0)
1205 {
1206 pad1 = w / (rows[rowNum].numTabs *
2);
1207 pad2 = pad1;
1208 if (fc->folder.firstInRow == True)
1209 pad2 += w - (pad1 * rows[rowNum].numTabs *
2);
1210 }
1211 x += pad1;
1212
1213
1214 XtMoveWidget(tab, x, y);
1215
1216
1217 x += pad2 + XtWidth(tab) + tab->core.border_width *
2 + ht +
1218 f->folder.marginWidth + co + st;
1219 fc->folder.width = x - fc->folder.x;
1220 x += f->folder.spacing;
1221 }
1222
1223
1224 for (i =
0; i < f->composite.num_children; i++)
1225 {
1226 child = children[i];
1227 if (XtIsSubclass(child, xmPrimitiveWidgetClass))
1228 continue;
1229 if (f->folder.resizePolicy == XmRESIZE_NONE)
1230 continue;
1231
1232 w = (
int)f->core.width - st *
2;
1233 h = (
int)f->core.height - (
int)f->folder.tabHeight - st *
2;
1234 if (h <=
0 || w <=
0)
1235 continue;
1236
1237
1238 isManaged = True;
1239 if (!XtIsManaged(child))
1240 {
1241 XtVaGetValues(child,
1242 XmNmappedWhenManaged, &map,
1243 NULL);
1244 XtVaSetValues(child,
1245 XmNmappedWhenManaged, False,
1246 NULL);
1247 XtManageChild(child);
1248 isManaged = False;
1249 }
1250 x = st;
1251 if (f->folder.tabPlacement == XmFOLDER_TOP)
1252 y = f->folder.tabHeight + st;
1253 else
1254 y = st;
1255 width = w;
1256 height = h;
1257 borderWidth =
0;
1258 if (XtIsWidget(child))
1259 borderWidth = child->core.border_width;
1260 XtConfigureWidget(child, x, y, width, height, borderWidth);
1261 if (isManaged == False)
1262 {
1263 XtUnmanageChild(child);
1264 XtVaSetValues(child, XmNmappedWhenManaged, map,
NULL);
1265 }
1266 }
1267 }
1268
1269 static void
1270 LayoutLeftRight(XmLFolderWidget f,
1271 int resizeIfNeeded)
1272 {
1273 Display *dpy;
1274 Window root;
1275 int i, tabNum, x, y, w, h, pad1, pad2;
1276 int rowNum, numRows, rowWidth, rowX, rowY;
1277 WidgetList children;
1278 Widget tab, child;
1279 XmLFolderConstraintRec *fc;
1280 XtGeometryResult result;
1281 unsigned int inactPixHeight, pixHeight;
1282 unsigned int inactPixWidth, pixWidth;
1283 unsigned int pixBW, pixDepth;
1284 Dimension height, minHeight;
1285 Dimension width, minWidth, borderWidth;
1286 Dimension co;
1287 int st, ht;
1288 Boolean map, isManaged;
1289 struct
1290 {
1291 int width, height, numTabs, x;
1292 } rows[
MAX_TAB_ROWS];
1293
1294 dpy = XtDisplay(f);
1295 children = f->composite.children;
1296 st = f->manager.shadow_thickness;
1297 ht = f->folder.highlightThickness;
1298
1299
1300 if (f->folder.cornerStyle == XmCORNER_LINE)
1301 co = (Dimension)((
double)f->folder.cornerDimension * .
5 + .
99);
1302 else if (f->folder.cornerStyle == XmCORNER_ARC)
1303 co = (Dimension)((
double)f->folder.cornerDimension * .
3 + .
99);
1304 else
1305 co =
0;
1306
1307
1308
1309 rowX =
0;
1310 rowY =
0;
1311 rowWidth =
0;
1312 rowNum =
0;
1313 tabNum =
0;
1314 minHeight =
0;
1315 for (i =
0; i < f->folder.tabCount; i++)
1316 {
1317 tab = f->folder.tabs[i];
1318 if (!XtIsManaged(tab))
1319 continue;
1320 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
1321
1322
1323 fc->folder.firstInRow = False;
1324 if (!tabNum)
1325 fc->folder.firstInRow = True;
1326 if (f->folder.tabsPerRow && tabNum == f->folder.tabsPerRow)
1327 {
1328 fc->folder.firstInRow = True;
1329
1330
1331 if (rowY)
1332 rowY -= f->folder.spacing;
1333 rows[rowNum].x = rowX;
1334 rows[rowNum].height = rowY;
1335 rows[rowNum].width = rowWidth;
1336 rows[rowNum].numTabs = tabNum;
1337 if (f->folder.debugLevel)
1338 {
1339 fprintf(stderr,
"XmLFolder: Layout: ");
1340 fprintf(stderr,
"row %d: x %d w %d h %d numTabs %d\n",
1341 rowNum, rowX, rowWidth, rowY, tabNum);
1342 }
1343 rowX += rowWidth;
1344 rowWidth =
0;
1345 if (rowY > (
int)minHeight)
1346 minHeight = rowY;
1347 rowY =
0;
1348 tabNum =
0;
1349 rowNum++;
1350 if (rowNum ==
MAX_TAB_ROWS -
1)
1351 {
1352 XmLWarning((Widget)f,
"Layout ERROR - too many rows\n");
1353 return;
1354 }
1355 }
1356
1357
1358 width = co + st + tab->core.width + tab->core.border_width *
2 +
1359 f->folder.marginHeight *
2 + ht *
2;
1360 if ((
int)width > rowWidth)
1361 rowWidth = width;
1362
1363
1364 pixWidth =
0;
1365 pixHeight =
0;
1366 fc->folder.pixWidth =
0;
1367 fc->folder.pixHeight =
0;
1368 fc->folder.inactPixWidth =
0;
1369 fc->folder.inactPixHeight =
0;
1370 fc->folder.maxPixWidth =
0;
1371 fc->folder.maxPixHeight =
0;
1372 if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
1373 {
1374 XGetGeometry(dpy, fc->folder.pix, &root,
1375 &x, &y, &pixWidth, &pixHeight, &pixBW, &pixDepth);
1376 fc->folder.pixWidth = pixWidth;
1377 fc->folder.maxPixWidth = pixWidth;
1378 fc->folder.pixHeight = pixHeight;
1379 fc->folder.maxPixHeight = pixHeight;
1380 width = co + st + pixWidth + f->folder.marginHeight *
2 + ht *
2;
1381 if ((
int)width > rowWidth)
1382 rowWidth = width;
1383 }
1384 if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
1385 {
1386 XGetGeometry(dpy, fc->folder.inactPix, &root, &x, &y,
1387 &inactPixWidth, &inactPixHeight, &pixBW, &pixDepth);
1388 fc->folder.inactPixWidth = inactPixWidth;
1389 if (inactPixWidth > fc->folder.maxPixWidth)
1390 fc->folder.maxPixWidth = inactPixWidth;
1391 fc->folder.inactPixHeight = inactPixHeight;
1392 if (inactPixHeight > fc->folder.maxPixHeight)
1393 fc->folder.maxPixHeight = inactPixHeight;
1394 width = co + st + inactPixWidth +
1395 f->folder.marginHeight *
2 + ht *
2;
1396 if ((
int)width > rowWidth)
1397 rowWidth = width;
1398 }
1399
1400
1401 rowY += st *
2 + co *
2 + f->folder.marginWidth *
2 + ht *
2 +
1402 XtHeight(tab) + tab->core.border_width *
2;
1403
1404 if (fc->folder.maxPixHeight)
1405 rowY += fc->folder.maxPixHeight + f->folder.pixmapMargin;
1406 rowY += f->folder.spacing;
1407
1408 tabNum++;
1409 fc->folder.row = rowNum;
1410 }
1411
1412
1413 if (rowY)
1414 rowY -= f->folder.spacing;
1415 rows[rowNum].x = rowX;
1416 rows[rowNum].height = rowY;
1417 rows[rowNum].width = rowWidth;
1418 rows[rowNum].numTabs = tabNum;
1419 numRows = rowNum +
1;
1420 if (f->folder.debugLevel)
1421 {
1422 fprintf(stderr,
"XmLFolder: Layout: ");
1423 fprintf(stderr,
"row %d: x %d w %d h %d numTabs %d\n",
1424 rowNum, rowX, rowWidth, rowY, tabNum);
1425 }
1426 f->folder.tabWidth = rowX + rowWidth;
1427 f->folder.tabBarHeight = f->folder.tabWidth;
1428 minWidth = f->folder.tabWidth;
1429 if ((
int)minHeight < rowY)
1430 minHeight = rowY;
1431
1432
1433 if (f->folder.tabsPerRow && minHeight)
1434 minHeight +=
4;
1435
1436 if (f->folder.debugLevel)
1437 {
1438 fprintf(stderr,
"XmLFolder: Layout: ");
1439 fprintf(stderr,
"tab bar minimum w %d h %d\n",
1440 (
int)minWidth, (
int)minHeight);
1441 }
1442
1443
1444
1445 for (i =
0; i < f->composite.num_children; i++)
1446 {
1447 child = children[i];
1448 if (XtIsSubclass(child, xmPrimitiveWidgetClass))
1449 continue;
1450
1451 height = XtHeight(child) + st *
2;
1452 if (XtIsWidget(child))
1453 height += f->core.border_width *
2;
1454 if (height > minHeight)
1455 minHeight = height;
1456
1457 width = XtWidth(child) + f->folder.tabWidth + st *
2;
1458 if (XtIsWidget(child))
1459 width += f->core.border_width *
2;
1460 if (width > minWidth)
1461 minWidth = width;
1462 }
1463
1464 if (f->folder.debugLevel)
1465 {
1466 fprintf(stderr,
"XmLFolder: Layout: ");
1467 fprintf(stderr,
"with non-tabs minimum w %d h %d\n",
1468 (
int)minWidth, (
int)minHeight);
1469 }
1470
1471
1472 if (resizeIfNeeded && f->folder.resizePolicy != XmRESIZE_NONE)
1473 {
1474 if (minWidth <=
0)
1475 minWidth =
1;
1476 if (minHeight <=
0)
1477 minHeight =
1;
1478 result = XtMakeResizeRequest((Widget)f, minWidth, minHeight,
1479 &width, &height);
1480 if (result == XtGeometryAlmost)
1481 XtMakeResizeRequest((Widget)f, width, height,
NULL,
NULL);
1482 }
1483
1484 tab = f->folder.activeW;
1485 if (tab)
1486 {
1487 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
1488 rowNum = fc->folder.row;
1489 f->folder.activeRow = rowNum;
1490 rows[rowNum].x = f->folder.tabWidth - rows[rowNum].width;
1491 for (i = rowNum +
1; i < numRows; i++)
1492 rows[i].x -= rows[rowNum].width;
1493 }
1494 else
1495 f->folder.activeRow = -
1;
1496
1497
1498 for (i =
0; i < f->folder.tabCount; i++)
1499 {
1500 tab = f->folder.tabs[i];
1501 if (!XtIsManaged(tab))
1502 continue;
1503 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
1504 rowNum = fc->folder.row;
1505
1506
1507 if (fc->folder.firstInRow == True)
1508 {
1509 if (f->folder.tabsPerRow && rowNum != f->folder.activeRow)
1510 y =
2;
1511 else
1512 y =
0;
1513 }
1514 fc->folder.y = y;
1515 y += st + co + f->folder.marginWidth + ht;
1516 if (fc->folder.maxPixHeight)
1517 y += fc->folder.maxPixHeight + f->folder.pixmapMargin;
1518
1519
1520 fc->folder.width = rows[rowNum].width;
1521 if (f->folder.tabPlacement == XmFOLDER_LEFT)
1522 {
1523 fc->folder.x = rows[rowNum].x;
1524 x = fc->folder.x + fc->folder.width - f->folder.marginHeight -
1525 ht - XtWidth(tab) - tab->core.border_width *
2;
1526 }
1527 else
1528 {
1529 fc->folder.x = f->core.width - rows[rowNum].x -
1530 rows[rowNum].width;
1531 x = fc->folder.x + f->folder.marginHeight + ht;
1532 }
1533
1534
1535 pad1 =
0;
1536 pad2 =
0;
1537 h = f->core.height - rows[rowNum].height;
1538 if (rowNum != f->folder.activeRow)
1539 h -=
4;
1540 if (f->folder.tabsPerRow && h >
0)
1541 {
1542 pad1 = h / (rows[rowNum].numTabs *
2);
1543 pad2 = pad1;
1544 if (fc->folder.firstInRow == True)
1545 pad2 += h - (pad1 * rows[rowNum].numTabs *
2);
1546 }
1547 y += pad1;
1548
1549
1550 XtMoveWidget(tab, x, y);
1551
1552
1553 y += pad2 + XtHeight(tab) + tab->core.border_width *
2 + ht +
1554 f->folder.marginWidth + co + st;
1555 fc->folder.height = y - fc->folder.y;
1556 y += f->folder.spacing;
1557 }
1558
1559
1560 for (i =
0; i < f->composite.num_children; i++)
1561 {
1562 child = children[i];
1563 if (XtIsSubclass(child, xmPrimitiveWidgetClass))
1564 continue;
1565 if (f->folder.resizePolicy == XmRESIZE_NONE)
1566 continue;
1567
1568 w = (
int)f->core.width - (
int)f->folder.tabWidth - st *
2;
1569 h = (
int)f->core.height - st *
2;
1570 if (h <=
0 || w <=
0)
1571 continue;
1572
1573
1574 isManaged = True;
1575 if (!XtIsManaged(child))
1576 {
1577 XtVaGetValues(child,
1578 XmNmappedWhenManaged, &map,
1579 NULL);
1580 XtVaSetValues(child,
1581 XmNmappedWhenManaged, False,
1582 NULL);
1583 XtManageChild(child);
1584 isManaged = False;
1585 }
1586 y = st;
1587 if (f->folder.tabPlacement == XmFOLDER_LEFT)
1588 x = f->folder.tabWidth + st;
1589 else
1590 x = st;
1591 width = w;
1592 height = h;
1593 borderWidth =
0;
1594 if (XtIsWidget(child))
1595 borderWidth = child->core.border_width;
1596 XtConfigureWidget(child, x, y, width, height, borderWidth);
1597 if (isManaged == False)
1598 {
1599 XtUnmanageChild(child);
1600 XtVaSetValues(child, XmNmappedWhenManaged, map,
NULL);
1601 }
1602 }
1603 }
1604
1605 static void
1606 Resize(Widget w)
1607 {
1608 XmLFolderWidget f;
1609
1610 f = (XmLFolderWidget)w;
1611 Layout(f,
0);
1612 }
1613
1614 static XtGeometryResult
1615 GeometryManager(Widget w,
1616 XtWidgetGeometry *request,
1617 XtWidgetGeometry *allow)
1618 {
1619 XmLFolderWidget f;
1620
1621 f = (XmLFolderWidget)XtParent(w);
1622 if (f->folder.resizePolicy != XmRESIZE_STATIC ||
1623 XtIsSubclass(w, xmPrimitiveWidgetClass))
1624 {
1625 if (request->request_mode & CWWidth)
1626 w->core.width = request->width;
1627 if (request->request_mode & CWHeight)
1628 w->core.height = request->height;
1629 if (request->request_mode &
CWX)
1630 w->core.x = request->x;
1631 if (request->request_mode &
CWY)
1632 w->core.y = request->y;
1633 if (request->request_mode & CWBorderWidth)
1634 w->core.border_width = request->border_width;
1635 Layout(f,
1);
1636 return XtGeometryYes;
1637 }
1638 return XtGeometryNo;
1639 }
1640
1641 static void
1642 ChangeManaged(Widget w)
1643 {
1644 XmLFolderWidget f;
1645
1646 f = (XmLFolderWidget)w;
1647 Layout(f,
1);
1648 _XmNavigChangeManaged(w);
1649 }
1650
1651 static void
1652 ConstraintInitialize(Widget req,
1653 Widget w,
1654 ArgList args,
1655 Cardinal *narg)
1656 {
1657 XmLFolderWidget f;
1658 XmLFolderConstraintRec *fc;
1659
1660 if (!XtIsRectObj(w))
1661 return;
1662 f = (XmLFolderWidget)XtParent(w);
1663 if (f->folder.debugLevel)
1664 fprintf(stderr,
"XmLFolder: Constraint Init\n");
1665 fc = (XmLFolderConstraintRec *)(w->core.constraints);
1666 fc->folder.x =
0;
1667 fc->folder.y =
0;
1668 fc->folder.width =
0;
1669 fc->folder.height =
0;
1670 fc->folder.maxPixWidth =
0;
1671 fc->folder.maxPixHeight =
0;
1672 fc->folder.row = -
1;
1673 fc->folder.firstInRow = False;
1674 if (fc->folder.managedName)
1675 fc->folder.managedName = (
char *)strdup(fc->folder.managedName);
1676 if (XtIsSubclass(w, xmPrimitiveWidgetClass))
1677 {
1678 XtOverrideTranslations(w, f->folder.primTrans);
1679 XtAddCallback(w, XmNactivateCallback, PrimActivate,
0);
1680 XtVaSetValues(w,
1681 XmNhighlightThickness,
0,
1682 XmNshadowThickness,
0,
1683 NULL);
1684 if (XtIsSubclass(w, xmLabelWidgetClass))
1685 XtVaSetValues(w, XmNfillOnArm, False,
NULL);
1686
1687
1688 if (f->folder.tabAllocCount < f->folder.tabCount +
1)
1689 {
1690 f->folder.tabAllocCount *=
2;
1691 f->folder.tabs = (Widget *)realloc((
char *)f->folder.tabs,
1692 sizeof(Widget) * f->folder.tabAllocCount);
1693 }
1694 f->folder.tabs[f->folder.tabCount++] = w;
1695
1696 }
1697 if (XmIsDrawnButton(w))
1698 SetTabPlacement(f, w);
1699
1700 #ifdef XmLEVAL
1701 if (f->folder.tabCount >
6)
1702 {
1703 fprintf(stderr,
"XmL: evaluation version only supports <= 6 tabs\n");
1704 exit(
0);
1705 }
1706 #endif
1707 }
1708
1709 static void
1710 ConstraintDestroy(Widget w)
1711 {
1712 XmLFolderWidget f;
1713 XmLFolderConstraintRec *fc;
1714 int i, j, activePos;
1715
1716 if (!XtIsRectObj(w))
1717 return;
1718 f = (XmLFolderWidget)XtParent(w);
1719 if (f->folder.debugLevel)
1720 fprintf(stderr,
"XmLFolder: Constraint Destroy\n");
1721 if (f->folder.focusW == w)
1722 f->folder.focusW =
0;
1723 fc = (XmLFolderConstraintRec *)(w->core.constraints);
1724 if (fc->folder.managedName)
1725 free((
char *)fc->folder.managedName);
1726 if (fc->folder.freePix == True)
1727 {
1728 if (fc->folder.pix != XmUNSPECIFIED_PIXMAP)
1729 XFreePixmap(XtDisplay(w), fc->folder.pix);
1730 if (fc->folder.inactPix != XmUNSPECIFIED_PIXMAP)
1731 XFreePixmap(XtDisplay(w), fc->folder.inactPix);
1732 }
1733 if (XtIsSubclass(w, xmPrimitiveWidgetClass))
1734 {
1735 XtRemoveCallback(w, XmNactivateCallback, PrimActivate,
0);
1736
1737
1738 activePos = -
1;
1739 j =
0;
1740 for (i =
0; i < f->folder.tabCount; i++)
1741 if (f->folder.tabs[i] != w)
1742 {
1743 if (f->folder.activeW == f->folder.tabs[i])
1744 activePos = j;
1745 f->folder.tabs[j++] = f->folder.tabs[i];
1746 }
1747 if (j != f->folder.tabCount -
1)
1748 XmLWarning((Widget)f,
"ConstraintDestroy() - bad child list");
1749 f->folder.tabCount = j;
1750 f->folder.activeTab = activePos;
1751 if (activePos == -
1)
1752 f->folder.activeW =
0;
1753 }
1754 }
1755
1756 static void
1757 DrawTabPixmap(XmLFolderWidget f,
1758 Widget tab,
1759 int active)
1760 {
1761 Display *dpy;
1762 Window win;
1763 int x, y;
1764 Pixmap pixmap;
1765 Dimension pixWidth, pixHeight, ht;
1766 XmLFolderConstraintRec *fc;
1767
1768 x =
0;
1769 y =
0;
1770 dpy = XtDisplay(f);
1771 win = XtWindow(f);
1772 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
1773 ht = f->folder.highlightThickness;
1774 if (active)
1775 {
1776 pixWidth = fc->folder.pixWidth;
1777 pixHeight = fc->folder.pixHeight;
1778 pixmap = fc->folder.pix;
1779 }
1780 else
1781 {
1782 pixWidth = fc->folder.inactPixWidth;
1783 pixHeight = fc->folder.inactPixHeight;
1784 pixmap = fc->folder.inactPix;
1785 }
1786 if (f->folder.tabPlacement == XmFOLDER_TOP)
1787 {
1788 x = tab->core.x - pixWidth - ht - f->folder.pixmapMargin;
1789 y = tab->core.y + tab->core.height - pixHeight;
1790 }
1791 else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
1792 {
1793 x = tab->core.x - fc->folder.pixWidth - ht - f->folder.pixmapMargin;
1794 y = tab->core.y;
1795 }
1796 else if (f->folder.tabPlacement == XmFOLDER_LEFT)
1797 {
1798 x = tab->core.x + tab->core.width - pixWidth;
1799 y = tab->core.y - pixHeight - f->folder.pixmapMargin - ht;
1800 }
1801 else if (f->folder.tabPlacement == XmFOLDER_RIGHT)
1802 {
1803 x = tab->core.x;
1804 y = tab->core.y - pixHeight - f->folder.pixmapMargin - ht;
1805 }
1806 XCopyArea(dpy, pixmap, win, f->folder.gc,
0,
0, pixWidth, pixHeight, x, y);
1807 }
1808
1809 static void
1810 DrawManagerShadowTopBottom(XmLFolderWidget f,
1811 XRectangle *rect)
1812 {
1813 Display *dpy;
1814 Window win;
1815 XmLFolderConstraintRec *fc;
1816 XSegment *topSeg, *botSeg;
1817 int i, bCount, tCount, st, botOff, isManaged;
1818
1819 dpy = XtDisplay(f);
1820 win = XtWindow(f);
1821 st = f->manager.shadow_thickness;
1822 if (!st)
1823 return;
1824 botOff = f->core.height - f->folder.tabHeight -
1;
1825
1826 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
1827 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
1828
1829
1830 fc =
0;
1831 if (f->folder.activeW)
1832 fc = (XmLFolderConstraintRec *)(f->folder.activeW->core.constraints);
1833 tCount =
0;
1834 if (fc)
1835 for (i =
0; i < st; i++)
1836 {
1837 topSeg[tCount].x1 = rect->x + i;
1838 topSeg[tCount].y1 = rect->y + i;
1839 topSeg[tCount].x2 = fc->folder.x + i;
1840 topSeg[tCount].y2 = rect->y + i;
1841 if (rect->x != fc->folder.x)
1842 tCount++;
1843 topSeg[tCount].x1 = rect->x + fc->folder.x +
1844 fc->folder.width - i -
1;
1845 topSeg[tCount].y1 = rect->y + i;
1846 topSeg[tCount].x2 = rect->x + rect->width - i -
1;
1847 topSeg[tCount].y2 = rect->y + i;
1848 if (fc->folder.x + fc->folder.width != rect->width)
1849 tCount++;
1850 }
1851 else
1852 for (i =
0; i < st; i++)
1853 {
1854 topSeg[tCount].x1 = rect->x + i;
1855 topSeg[tCount].y1 = rect->y + i;
1856 topSeg[tCount].x2 = rect->x + rect->width - i -
1;
1857 topSeg[tCount].y2 = rect->y + i;
1858 tCount++;
1859 }
1860 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
1861 for (i =
0 ; i < tCount; i++)
1862 {
1863 topSeg[i].y1 = botOff - topSeg[i].y1;
1864 topSeg[i].y2 = botOff - topSeg[i].y2;
1865 }
1866 if (tCount)
1867 {
1868 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
1869 SetGC(f,
GC_SHADOWBOT);
1870 else
1871 SetGC(f,
GC_SHADOWTOP);
1872 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
1873 SetGC(f,
GC_UNSET);
1874 }
1875
1876
1877 isManaged =
0;
1878 for (i =
0; i < f->composite.num_children; i++)
1879 {
1880 Widget child = f->composite.children[i];
1881 if (!XtIsSubclass(child, xmPrimitiveWidgetClass) && XtIsManaged(child))
1882 {
1883 isManaged =
1;
1884 break;
1885 }
1886
1887 }
1888
1889
1890
1891 if (!isManaged)
1892 {
1893 free((
char *)topSeg);
1894 free((
char *)botSeg);
1895 return;
1896 }
1897
1898
1899 tCount =
0;
1900 for (i =
0; i < st; i++)
1901 {
1902 topSeg[tCount].x1 = rect->x + i;
1903 topSeg[tCount].y1 = rect->y + i;
1904 topSeg[tCount].x2 = rect->x + i;
1905 topSeg[tCount].y2 = rect->y + rect->height - i -
1;
1906 tCount++;
1907 }
1908 if (tCount)
1909 {
1910 SetGC(f,
GC_SHADOWTOP);
1911 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
1912 SetGC(f,
GC_UNSET);
1913 }
1914
1915
1916 bCount =
0;
1917 for (i =
0; i < st; i++)
1918 {
1919 botSeg[bCount].x1 = rect->x + rect->width - i -
1;
1920 botSeg[bCount].y1 = rect->y + i;
1921 botSeg[bCount].x2 = rect->x + rect->width - i -
1;
1922 botSeg[bCount].y2 = rect->y + rect->height - i -
1;
1923 bCount++;
1924 }
1925 if (bCount)
1926 {
1927 SetGC(f,
GC_SHADOWBOT);
1928 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
1929 SetGC(f,
GC_UNSET);
1930 }
1931
1932
1933 bCount =
0;
1934 for (i =
0; i < st; i++)
1935 {
1936 botSeg[bCount].x1 = rect->x + i;
1937 botSeg[bCount].y1 = rect->y + rect->height - i -
1;
1938 botSeg[bCount].x2 = rect->x + rect->width - i -
1;
1939 botSeg[bCount].y2 = rect->y + rect->height - i -
1;
1940 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
1941 {
1942 botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
1943 botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
1944 }
1945 bCount++;
1946 }
1947 if (bCount)
1948 {
1949 if (f->folder.tabPlacement == XmFOLDER_TOP)
1950 SetGC(f,
GC_SHADOWBOT);
1951 else
1952 SetGC(f,
GC_SHADOWTOP);
1953 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
1954 SetGC(f,
GC_UNSET);
1955 }
1956 free((
char *)topSeg);
1957 free((
char *)botSeg);
1958 }
1959
1960 static void
1961 DrawManagerShadowLeftRight(XmLFolderWidget f,
1962 XRectangle *rect)
1963 {
1964 Display *dpy;
1965 Window win;
1966 XmLFolderConstraintRec *fc;
1967 XSegment *topSeg, *botSeg;
1968 int i, bCount, tCount, st, rightOff;
1969
1970 dpy = XtDisplay(f);
1971 win = XtWindow(f);
1972 st = f->manager.shadow_thickness;
1973 if (!st)
1974 return;
1975 rightOff = f->core.width - f->folder.tabWidth -
1;
1976
1977 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
1978 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
1979
1980
1981 fc =
0;
1982 if (f->folder.activeW)
1983 fc = (XmLFolderConstraintRec *)(f->folder.activeW->core.constraints);
1984 tCount =
0;
1985 if (fc)
1986 for (i =
0; i < st; i++)
1987 {
1988 topSeg[tCount].x1 = rect->x + i;
1989 topSeg[tCount].y1 = rect->y + i;
1990 topSeg[tCount].x2 = rect->x + i;
1991 topSeg[tCount].y2 = fc->folder.y + i;
1992 if (rect->y != fc->folder.y)
1993 tCount++;
1994 topSeg[tCount].x1 = rect->x + i;
1995 topSeg[tCount].y1 = rect->y + fc->folder.y +
1996 fc->folder.height - i -
1;
1997 topSeg[tCount].x2 = rect->x + i;
1998 topSeg[tCount].y2 = rect->y + rect->height - i -
1;
1999 if (fc->folder.y + fc->folder.height != rect->height)
2000 tCount++;
2001 }
2002 else
2003 for (i =
0; i < st; i++)
2004 {
2005 topSeg[tCount].x1 = rect->x + i;
2006 topSeg[tCount].y1 = rect->y + i;
2007 topSeg[tCount].x2 = rect->x + i;
2008 topSeg[tCount].y2 = rect->y + rect->height - i -
1;
2009 tCount++;
2010 }
2011 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2012 for (i =
0 ; i < tCount; i++)
2013 {
2014 topSeg[i].x1 = rightOff - topSeg[i].x1;
2015 topSeg[i].x2 = rightOff - topSeg[i].x2;
2016 }
2017 if (tCount)
2018 {
2019 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2020 SetGC(f,
GC_SHADOWBOT);
2021 else
2022 SetGC(f,
GC_SHADOWTOP);
2023 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2024 SetGC(f,
GC_UNSET);
2025 }
2026
2027
2028 tCount =
0;
2029 for (i =
0; i < st; i++)
2030 {
2031 topSeg[tCount].x1 = rect->x + i;
2032 topSeg[tCount].y1 = rect->y + i;
2033 topSeg[tCount].x2 = rect->x + rect->width - i -
1;
2034 topSeg[tCount].y2 = rect->y + i;
2035 tCount++;
2036 }
2037 if (tCount)
2038 {
2039 SetGC(f,
GC_SHADOWTOP);
2040 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2041 SetGC(f,
GC_UNSET);
2042 }
2043
2044
2045 bCount =
0;
2046 for (i =
0; i < st; i++)
2047 {
2048 botSeg[bCount].x1 = rect->x + i;
2049 botSeg[bCount].y1 = rect->y + rect->height - i -
1;
2050 botSeg[bCount].x2 = rect->x + rect->width - i -
1;
2051 botSeg[bCount].y2 = rect->y + rect->height - i -
1;
2052 bCount++;
2053 }
2054 if (bCount)
2055 {
2056 SetGC(f,
GC_SHADOWBOT);
2057 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2058 SetGC(f,
GC_UNSET);
2059 }
2060
2061
2062 bCount =
0;
2063 for (i =
0; i < st; i++)
2064 {
2065 botSeg[bCount].x1 = rect->x + rect->width - i -
1;
2066 botSeg[bCount].y1 = rect->y + i;
2067 botSeg[bCount].x2 = rect->x + rect->width - i -
1;
2068 botSeg[bCount].y2 = rect->y + rect->height - i -
1;
2069 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2070 {
2071 botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
2072 botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
2073 }
2074 bCount++;
2075 }
2076 if (bCount)
2077 {
2078 if (f->folder.tabPlacement == XmFOLDER_LEFT)
2079 SetGC(f,
GC_SHADOWBOT);
2080 else
2081 SetGC(f,
GC_SHADOWTOP);
2082 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2083 SetGC(f,
GC_UNSET);
2084 }
2085 free((
char *)topSeg);
2086 free((
char *)botSeg);
2087 }
2088
2089 static void
2090 DrawTabShadowArcTopBottom(XmLFolderWidget f,
2091 Widget w)
2092 {
2093 XmLFolderConstraintRec *fc;
2094 Display *dpy;
2095 Window win;
2096 XSegment *topSeg, *botSeg;
2097 XRectangle rect, rect2;
2098 XArc arc;
2099 int tCount, bCount;
2100 int i, st, cd, botOff;
2101
2102 dpy = XtDisplay(f);
2103 win = XtWindow(f);
2104 fc = (XmLFolderConstraintRec *)(w->core.constraints);
2105 botOff =
2 * fc->folder.y + fc->folder.height -
1;
2106 st = f->manager.shadow_thickness;
2107 if (!st)
2108 return;
2109 cd = f->folder.cornerDimension;
2110
2111 tCount =
0;
2112 bCount =
0;
2113 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2114 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2115 for (i =
0; i < st; i++)
2116 {
2117
2118 topSeg[tCount].x1 = fc->folder.x + i;
2119 topSeg[tCount].y1 = fc->folder.y + cd + st;
2120 topSeg[tCount].x2 = fc->folder.x + i;
2121 topSeg[tCount].y2 = fc->folder.y + fc->folder.height -
1;
2122 if (w == f->folder.activeW)
2123 topSeg[tCount].y2 += i;
2124 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2125 {
2126 topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
2127 topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
2128 }
2129 tCount++;
2130
2131
2132 botSeg[bCount].x1 = fc->folder.x + fc->folder.width - i -
1;
2133 botSeg[bCount].y1 = fc->folder.y + cd + st;
2134 botSeg[bCount].x2 = fc->folder.x + fc->folder.width - i -
1;
2135 botSeg[bCount].y2 = fc->folder.y + fc->folder.height -
1;
2136 if (w == f->folder.activeW)
2137 botSeg[bCount].y2 += i;
2138 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2139 {
2140 botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
2141 botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
2142 }
2143 bCount++;
2144 }
2145 if (tCount)
2146 {
2147 SetGC(f,
GC_SHADOWTOP);
2148 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2149 SetGC(f,
GC_UNSET);
2150 }
2151 if (bCount)
2152 {
2153 SetGC(f,
GC_SHADOWBOT);
2154 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2155 SetGC(f,
GC_UNSET);
2156 }
2157 tCount =
0;
2158 for (i =
0; i < st; i++)
2159 {
2160
2161 topSeg[tCount].x1 = fc->folder.x + cd + st;
2162 topSeg[tCount].y1 = fc->folder.y + i;
2163 topSeg[tCount].x2 = fc->folder.x + fc->folder.width - cd - st -
1;
2164 topSeg[tCount].y2 = fc->folder.y + i;
2165 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2166 {
2167 topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
2168 topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
2169 }
2170 tCount++;
2171 }
2172 if (tCount)
2173 {
2174 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2175 SetGC(f,
GC_SHADOWBOT);
2176 else
2177 SetGC(f,
GC_SHADOWTOP);
2178 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2179 SetGC(f,
GC_UNSET);
2180 }
2181 free((
char *)topSeg);
2182 free((
char *)botSeg);
2183
2184
2185 rect.x = fc->folder.x;
2186 rect.y = fc->folder.y;
2187 rect.width = cd + st;
2188 rect.height = cd + st;
2189 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2190 rect.y = fc->folder.y + fc->folder.height - rect.height;
2191 SetGC(f,
GC_BLANK);
2192 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
2193 rect.width, rect.height);
2194 SetGC(f,
GC_UNSET);
2195
2196
2197
2198
2199 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect,
1, Unsorted);
2200 arc.x = rect.x;
2201 arc.y = rect.y;
2202 arc.width = rect.width *
2;
2203 arc.height = rect.height *
2;
2204 if (f->folder.serverDrawsArcsLarge == True)
2205 {
2206 arc.width -=
1;
2207 arc.height -=
1;
2208 }
2209 arc.angle1 =
0 *
64;
2210 arc.angle2 =
360 *
64;
2211 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2212 arc.y = fc->folder.y + fc->folder.height - arc.height;
2213 SetGC(f,
GC_SHADOWTOP);
2214 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2215 arc.angle1, arc.angle2);
2216 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2217 arc.angle1, arc.angle2);
2218 SetGC(f,
GC_UNSET);
2219
2220 rect2 = rect;
2221 rect2.x += st;
2222 rect2.width -= st;
2223 rect2.height -= st;
2224 if (f->folder.tabPlacement == XmFOLDER_TOP)
2225 rect2.y += st;
2226 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect2,
1, Unsorted);
2227 if (w == f->folder.activeW)
2228 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2229 else
2230 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2231 arc.x += st;
2232 arc.y += st;
2233 arc.width -= st *
2;
2234 arc.height -= st *
2;
2235 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2236 arc.angle1, arc.angle2);
2237 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2238 arc.angle1, arc.angle2);
2239 XSetClipMask(dpy, f->folder.gc, None);
2240
2241
2242 rect.x = fc->folder.x + fc->folder.width - cd - st;
2243 SetGC(f,
GC_BLANK);
2244 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
2245 rect.width, rect.height);
2246 SetGC(f,
GC_UNSET);
2247
2248
2249 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect,
1, Unsorted);
2250 arc.x = rect.x - cd - st;
2251 arc.y = rect.y;
2252 arc.width = rect.width *
2;
2253 arc.height = rect.height *
2;
2254 if (f->folder.serverDrawsArcsLarge == True)
2255 {
2256 arc.width -=
1;
2257 arc.height -=
1;
2258 }
2259 arc.angle1 =
0 *
64;
2260 arc.angle2 =
360 *
64;
2261 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2262 arc.y = fc->folder.y + fc->folder.height - arc.height;
2263 SetGC(f,
GC_SHADOWBOT);
2264 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2265 arc.angle1, arc.angle2);
2266 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2267 arc.angle1, arc.angle2);
2268 SetGC(f,
GC_UNSET);
2269
2270 rect2 = rect;
2271 rect2.width -= st;
2272 rect2.height -= st;
2273 if (f->folder.tabPlacement == XmFOLDER_TOP)
2274 rect2.y += st;
2275 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect2,
1, Unsorted);
2276 if (w == f->folder.activeW)
2277 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2278 else
2279 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2280 arc.x += st;
2281 arc.y += st;
2282 arc.width -= st *
2;
2283 arc.height -= st *
2;
2284 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2285 arc.angle1, arc.angle2);
2286 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2287 arc.angle1, arc.angle2);
2288 XSetClipMask(dpy, f->folder.gc, None);
2289 }
2290
2291 static void
2292 DrawTabShadowArcLeftRight(XmLFolderWidget f,
2293 Widget w)
2294 {
2295 XmLFolderConstraintRec *fc;
2296 Display *dpy;
2297 Window win;
2298 XSegment *topSeg, *botSeg;
2299 XRectangle rect, rect2;
2300 XArc arc;
2301 int tCount, bCount;
2302 int i, st, cd, rightOff;
2303
2304 dpy = XtDisplay(f);
2305 win = XtWindow(f);
2306 fc = (XmLFolderConstraintRec *)(w->core.constraints);
2307 rightOff =
2 * fc->folder.x + fc->folder.width -
1;
2308 st = f->manager.shadow_thickness;
2309 if (!st)
2310 return;
2311 cd = f->folder.cornerDimension;
2312
2313 tCount =
0;
2314 bCount =
0;
2315 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2316 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2317 for (i =
0; i < st; i++)
2318 {
2319
2320 topSeg[tCount].x1 = fc->folder.x + cd + st;
2321 topSeg[tCount].y1 = fc->folder.y + i;
2322 topSeg[tCount].x2 = fc->folder.x + fc->folder.width -
1;
2323 if (w == f->folder.activeW)
2324 topSeg[tCount].x2 += i;
2325 topSeg[tCount].y2 = fc->folder.y + i;
2326 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2327 {
2328 topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
2329 topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
2330 }
2331 tCount++;
2332
2333
2334 botSeg[bCount].x1 = fc->folder.x + cd + st;
2335 botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i -
1;
2336 botSeg[bCount].x2 = fc->folder.x + fc->folder.width -
1;
2337 if (w == f->folder.activeW)
2338 botSeg[bCount].x2 += i;
2339 botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i -
1;
2340 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2341 {
2342 botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
2343 botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
2344 }
2345 bCount++;
2346 }
2347 if (tCount)
2348 {
2349 SetGC(f,
GC_SHADOWTOP);
2350 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2351 SetGC(f,
GC_UNSET);
2352 }
2353 if (bCount)
2354 {
2355 SetGC(f,
GC_SHADOWBOT);
2356 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2357 SetGC(f,
GC_UNSET);
2358 }
2359 tCount =
0;
2360 for (i =
0; i < st; i++)
2361 {
2362
2363 topSeg[tCount].x1 = fc->folder.x + i;
2364 topSeg[tCount].y1 = fc->folder.y + cd + st;
2365 topSeg[tCount].x2 = fc->folder.x + i;
2366 topSeg[tCount].y2 = fc->folder.y + fc->folder.height - cd - st -
1;
2367 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2368 {
2369 topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
2370 topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
2371 }
2372 tCount++;
2373 }
2374 if (tCount)
2375 {
2376 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2377 SetGC(f,
GC_SHADOWBOT);
2378 else
2379 SetGC(f,
GC_SHADOWTOP);
2380 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2381 SetGC(f,
GC_UNSET);
2382 }
2383 free((
char *)topSeg);
2384 free((
char *)botSeg);
2385
2386
2387 rect.x = fc->folder.x;
2388 rect.y = fc->folder.y;
2389 rect.width = cd + st;
2390 rect.height = cd + st;
2391 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2392 rect.x = fc->folder.x + fc->folder.width - rect.width;
2393 SetGC(f,
GC_BLANK);
2394 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
2395 rect.width, rect.height);
2396 SetGC(f,
GC_UNSET);
2397
2398
2399 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect,
1, Unsorted);
2400 arc.x = rect.x;
2401 arc.y = rect.y;
2402 arc.width = rect.width *
2;
2403 arc.height = rect.height *
2;
2404 if (f->folder.serverDrawsArcsLarge == True)
2405 {
2406 arc.width -=
1;
2407 arc.height -=
1;
2408 }
2409 arc.angle1 =
0 *
64;
2410 arc.angle2 =
360 *
64;
2411 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2412 arc.x = fc->folder.x + fc->folder.width - arc.width;
2413 SetGC(f,
GC_SHADOWTOP);
2414 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2415 arc.angle1, arc.angle2);
2416 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2417 arc.angle1, arc.angle2);
2418 SetGC(f,
GC_UNSET);
2419
2420 rect2 = rect;
2421 rect2.width -= st;
2422 rect2.height -= st;
2423 rect2.y += st;
2424 if (f->folder.tabPlacement == XmFOLDER_LEFT)
2425 rect2.x += st;
2426 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect2,
1, Unsorted);
2427 if (w == f->folder.activeW)
2428 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2429 else
2430 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2431 arc.x += st;
2432 arc.y += st;
2433 arc.width -= st *
2;
2434 arc.height -= st *
2;
2435 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2436 arc.angle1, arc.angle2);
2437 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2438 arc.angle1, arc.angle2);
2439 XSetClipMask(dpy, f->folder.gc, None);
2440
2441
2442 rect.y = fc->folder.y + fc->folder.height - cd - st;
2443 SetGC(f,
GC_BLANK);
2444 XFillRectangle(dpy, win, f->folder.gc, rect.x, rect.y,
2445 rect.width, rect.height);
2446 SetGC(f,
GC_UNSET);
2447
2448
2449 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect,
1, Unsorted);
2450 arc.x = rect.x;
2451 arc.y = rect.y - cd - st;
2452 arc.width = rect.width *
2;
2453 arc.height = rect.height *
2;
2454 if (f->folder.serverDrawsArcsLarge == True)
2455 {
2456 arc.width -=
1;
2457 arc.height -=
1;
2458 }
2459 arc.angle1 =
0 *
64;
2460 arc.angle2 =
360 *
64;
2461 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2462 arc.x = fc->folder.x + fc->folder.width - arc.width;
2463 SetGC(f,
GC_SHADOWBOT);
2464 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2465 arc.angle1, arc.angle2);
2466 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2467 arc.angle1, arc.angle2);
2468 SetGC(f,
GC_UNSET);
2469
2470 rect2 = rect;
2471 rect2.width -= st;
2472 rect2.height -= st;
2473 if (f->folder.tabPlacement == XmFOLDER_LEFT)
2474 rect2.x += st;
2475 XSetClipRectangles(dpy, f->folder.gc,
0,
0, &rect2,
1, Unsorted);
2476 if (w == f->folder.activeW)
2477 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2478 else
2479 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2480 arc.x += st;
2481 arc.y += st;
2482 arc.width -= st *
2;
2483 arc.height -= st *
2;
2484 XFillArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2485 arc.angle1, arc.angle2);
2486 XDrawArc(dpy, win, f->folder.gc, arc.x, arc.y, arc.width, arc.height,
2487 arc.angle1, arc.angle2);
2488 XSetClipMask(dpy, f->folder.gc, None);
2489 }
2490
2491 static void
2492 DrawTabShadowLineTopBottom(XmLFolderWidget f,
2493 Widget w)
2494 {
2495 XmLFolderConstraintRec *fc;
2496 Display *dpy;
2497 Window win;
2498 XSegment *topSeg, *botSeg;
2499 XPoint points[
4];
2500 int tCount, bCount, botOff, i, st, cd, y;
2501
2502 dpy = XtDisplay(f);
2503 win = XtWindow(f);
2504 fc = (XmLFolderConstraintRec *)(w->core.constraints);
2505 botOff =
2 * fc->folder.y + fc->folder.height -
1;
2506 st = f->manager.shadow_thickness;
2507 if (!st)
2508 return;
2509 cd = f->folder.cornerDimension;
2510
2511 tCount =
0;
2512 bCount =
0;
2513 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2514 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2515 for (i =
0; i < st; i++)
2516 {
2517
2518 topSeg[tCount].x1 = fc->folder.x + i;
2519 topSeg[tCount].y1 = fc->folder.y + cd + st;
2520 topSeg[tCount].x2 = fc->folder.x + i;
2521 topSeg[tCount].y2 = fc->folder.y + fc->folder.height -
1;
2522 if (w == f->folder.activeW)
2523 topSeg[tCount].y2 += i;
2524 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2525 {
2526 topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
2527 topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
2528 }
2529 tCount++;
2530
2531 botSeg[bCount].x1 = fc->folder.x + fc->folder.width - i -
1;
2532 botSeg[bCount].y1 = fc->folder.y + cd + st;
2533 botSeg[bCount].x2 = fc->folder.x + fc->folder.width - i -
1;
2534 botSeg[bCount].y2 = fc->folder.y + fc->folder.height -
1;
2535 if (w == f->folder.activeW)
2536 botSeg[bCount].y2 += i;
2537 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2538 {
2539 botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
2540 botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
2541 }
2542 bCount++;
2543 }
2544 if (tCount)
2545 {
2546 SetGC(f,
GC_SHADOWTOP);
2547 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2548 SetGC(f,
GC_UNSET);
2549 }
2550 if (bCount)
2551 {
2552 SetGC(f,
GC_SHADOWBOT);
2553 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2554 SetGC(f,
GC_UNSET);
2555 }
2556 tCount =
0;
2557 for (i =
0; i < st; i++)
2558 {
2559
2560 topSeg[tCount].x1 = fc->folder.x + cd + st;
2561 topSeg[tCount].y1 = fc->folder.y + i;
2562 topSeg[tCount].x2 = fc->folder.x + fc->folder.width - cd - st -
1;
2563 topSeg[tCount].y2 = fc->folder.y + i;
2564 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2565 {
2566 topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
2567 topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
2568 }
2569 tCount++;
2570 }
2571 if (tCount)
2572 {
2573 if (f->folder.tabPlacement == XmFOLDER_TOP)
2574 SetGC(f,
GC_SHADOWTOP);
2575 else
2576 SetGC(f,
GC_SHADOWBOT);
2577 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2578 SetGC(f,
GC_UNSET);
2579 }
2580 free((
char *)topSeg);
2581 free((
char *)botSeg);
2582
2583
2584 points[
0].x = fc->folder.x;
2585 points[
0].y = fc->folder.y + cd + st -
1;
2586 points[
1].x = fc->folder.x + cd + st -
1;
2587 points[
1].y = fc->folder.y;
2588 points[
2].x = fc->folder.x + cd + st -
1;
2589 points[
2].y = fc->folder.y + cd + st -
1;
2590 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2591 {
2592 points[
0].y = botOff - points[
0].y;
2593 points[
1].y = botOff - points[
1].y;
2594 points[
2].y = botOff - points[
2].y;
2595 }
2596 y = fc->folder.y;
2597 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2598 y = fc->folder.y + fc->folder.height - cd - st;
2599 SetGC(f,
GC_BLANK);
2600 XFillRectangle(dpy, win, f->folder.gc, fc->folder.x, y, cd + st, cd + st);
2601 SetGC(f,
GC_UNSET);
2602 SetGC(f,
GC_SHADOWTOP);
2603 XFillPolygon(dpy, win, f->folder.gc, points,
3, Nonconvex,
2604 CoordModeOrigin);
2605 points[
3].x = points[
0].x;
2606 points[
3].y = points[
0].y;
2607 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2608 SetGC(f,
GC_UNSET);
2609 if (w == f->folder.activeW)
2610 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2611 else
2612 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2613 points[
0].x += st;
2614 points[
1].y += st;
2615 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2616 points[
1].y -= st *
2;
2617 XFillPolygon(dpy, win, f->folder.gc, points,
3,
2618 Nonconvex, CoordModeOrigin);
2619 points[
3].x = points[
0].x;
2620 points[
3].y = points[
0].y;
2621 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2622
2623
2624 points[
0].x = fc->folder.x + fc->folder.width -
1;
2625 points[
0].y = fc->folder.y + cd + st -
1;
2626 points[
1].x = fc->folder.x + fc->folder.width - cd - st;
2627 points[
1].y = fc->folder.y;
2628 points[
2].x = fc->folder.x + fc->folder.width - cd - st;
2629 points[
2].y = fc->folder.y + cd + st -
1;
2630 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2631 {
2632 points[
0].y = botOff - points[
0].y;
2633 points[
1].y = botOff - points[
1].y;
2634 points[
2].y = botOff - points[
2].y;
2635 }
2636 y = fc->folder.y;
2637 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2638 y = fc->folder.y + fc->folder.height - cd - st;
2639 SetGC(f,
GC_BLANK);
2640 XFillRectangle(dpy, win, f->folder.gc, fc->folder.x + fc->folder.width -
2641 cd - st, y, cd + st, cd + st);
2642 SetGC(f,
GC_UNSET);
2643 if (f->folder.tabPlacement == XmFOLDER_TOP)
2644 SetGC(f,
GC_SHADOWTOP);
2645 else
2646 SetGC(f,
GC_SHADOWBOT);
2647 XFillPolygon(dpy, win, f->folder.gc, points,
3, Nonconvex,
2648 CoordModeOrigin);
2649 points[
3].x = points[
0].x;
2650 points[
3].y = points[
0].y;
2651 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2652 SetGC(f,
GC_UNSET);
2653 if (w == f->folder.activeW)
2654 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2655 else
2656 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2657 points[
0].x -= st;
2658 points[
1].y += st;
2659 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2660 points[
1].y -= st *
2;
2661 XFillPolygon(dpy, win, f->folder.gc, points,
3, Nonconvex,
2662 CoordModeOrigin);
2663 points[
3].x = points[
0].x;
2664 points[
3].y = points[
0].y;
2665 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2666 }
2667
2668 static void
2669 DrawTabShadowLineLeftRight(XmLFolderWidget f,
2670 Widget w)
2671 {
2672 XmLFolderConstraintRec *fc;
2673 Display *dpy;
2674 Window win;
2675 XSegment *topSeg, *botSeg;
2676 XPoint points[
4];
2677 int tCount, bCount, rightOff, i, st, cd, x;
2678
2679 dpy = XtDisplay(f);
2680 win = XtWindow(f);
2681 fc = (XmLFolderConstraintRec *)(w->core.constraints);
2682 rightOff =
2 * fc->folder.x + fc->folder.width -
1;
2683 st = f->manager.shadow_thickness;
2684 if (!st)
2685 return;
2686 cd = f->folder.cornerDimension;
2687
2688 tCount =
0;
2689 bCount =
0;
2690 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2691 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st);
2692 for (i =
0; i < st; i++)
2693 {
2694
2695 topSeg[tCount].x1 = fc->folder.x + cd + st;
2696 topSeg[tCount].y1 = fc->folder.y + i;
2697 topSeg[tCount].x2 = fc->folder.x + fc->folder.width -
1;
2698 if (w == f->folder.activeW)
2699 topSeg[tCount].x2 += i;
2700 topSeg[tCount].y2 = fc->folder.y + i;
2701 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2702 {
2703 topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
2704 topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
2705 }
2706 tCount++;
2707
2708 botSeg[bCount].x1 = fc->folder.x + cd + st;
2709 botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i -
1;
2710 botSeg[bCount].x2 = fc->folder.x + fc->folder.width -
1;
2711 if (w == f->folder.activeW)
2712 botSeg[bCount].x2 += i;
2713 botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i -
1;
2714 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2715 {
2716 botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
2717 botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
2718 }
2719 bCount++;
2720 }
2721 if (tCount)
2722 {
2723 SetGC(f,
GC_SHADOWTOP);
2724 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2725 SetGC(f,
GC_UNSET);
2726 }
2727 if (bCount)
2728 {
2729 SetGC(f,
GC_SHADOWBOT);
2730 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2731 SetGC(f,
GC_UNSET);
2732 }
2733 tCount =
0;
2734 for (i =
0; i < st; i++)
2735 {
2736
2737 topSeg[tCount].x1 = fc->folder.x + i;
2738 topSeg[tCount].y1 = fc->folder.y + cd + st;
2739 topSeg[tCount].x2 = fc->folder.x + i;
2740 topSeg[tCount].y2 = fc->folder.y + fc->folder.height - cd - st -
1;
2741 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2742 {
2743 topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
2744 topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
2745 }
2746 tCount++;
2747 }
2748 if (tCount)
2749 {
2750 if (f->folder.tabPlacement == XmFOLDER_LEFT)
2751 SetGC(f,
GC_SHADOWTOP);
2752 else
2753 SetGC(f,
GC_SHADOWBOT);
2754 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2755 SetGC(f,
GC_UNSET);
2756 }
2757 free((
char *)topSeg);
2758 free((
char *)botSeg);
2759
2760
2761 points[
0].x = fc->folder.x + cd + st -
1;
2762 points[
0].y = fc->folder.y;
2763 points[
1].x = fc->folder.x;
2764 points[
1].y = fc->folder.y + cd + st -
1;
2765 points[
2].x = fc->folder.x + cd + st -
1;
2766 points[
2].y = fc->folder.y + cd + st -
1;
2767 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2768 {
2769 points[
0].x = rightOff - points[
0].x;
2770 points[
1].x = rightOff - points[
1].x;
2771 points[
2].x = rightOff - points[
2].x;
2772 }
2773 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2774 x = fc->folder.x + fc->folder.width - cd - st;
2775 else
2776 x = fc->folder.x;
2777 SetGC(f,
GC_BLANK);
2778 XFillRectangle(dpy, win, f->folder.gc, x, fc->folder.y, cd + st, cd + st);
2779 SetGC(f,
GC_UNSET);
2780 SetGC(f,
GC_SHADOWTOP);
2781 XFillPolygon(dpy, win, f->folder.gc, points,
3, Nonconvex,
2782 CoordModeOrigin);
2783 points[
3].x = points[
0].x;
2784 points[
3].y = points[
0].y;
2785 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2786 SetGC(f,
GC_UNSET);
2787 if (w == f->folder.activeW)
2788 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2789 else
2790 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2791 points[
0].y += st;
2792 points[
1].x += st;
2793 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2794 points[
1].x -= st *
2;
2795 XFillPolygon(dpy, win, f->folder.gc, points,
3,
2796 Nonconvex, CoordModeOrigin);
2797 points[
3].x = points[
0].x;
2798 points[
3].y = points[
0].y;
2799 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2800
2801
2802 points[
0].x = fc->folder.x + cd + st -
1;
2803 points[
0].y = fc->folder.y + fc->folder.height -
1;
2804 points[
1].x = fc->folder.x;
2805 points[
1].y = fc->folder.y + fc->folder.height - cd - st;
2806 points[
2].x = fc->folder.x + cd + st -
1;
2807 points[
2].y = fc->folder.y + fc->folder.height - cd - st;
2808 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2809 {
2810 points[
0].x = rightOff - points[
0].x;
2811 points[
1].x = rightOff - points[
1].x;
2812 points[
2].x = rightOff - points[
2].x;
2813 }
2814 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2815 x = fc->folder.x + fc->folder.width - cd - st;
2816 else
2817 x = fc->folder.x;
2818 SetGC(f,
GC_BLANK);
2819 XFillRectangle(dpy, win, f->folder.gc, x, fc->folder.y +
2820 fc->folder.height - cd - st, cd + st, cd + st);
2821 SetGC(f,
GC_UNSET);
2822 SetGC(f,
GC_SHADOWBOT);
2823 XFillPolygon(dpy, win, f->folder.gc, points,
3, Nonconvex,
2824 CoordModeOrigin);
2825 points[
3].x = points[
0].x;
2826 points[
3].y = points[
0].y;
2827 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2828 SetGC(f,
GC_UNSET);
2829 if (w == f->folder.activeW)
2830 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
2831 else
2832 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
2833 points[
0].y -= st;
2834 points[
1].x += st;
2835 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2836 points[
1].x -= st *
2;
2837 XFillPolygon(dpy, win, f->folder.gc, points,
3, Nonconvex,
2838 CoordModeOrigin);
2839 points[
3].x = points[
0].x;
2840 points[
3].y = points[
0].y;
2841 XDrawLines(dpy, win, f->folder.gc, points,
4, CoordModeOrigin);
2842 }
2843
2844 static void
2845 DrawTabShadowNoneTopBottom(XmLFolderWidget f,
2846 Widget w)
2847 {
2848 XmLFolderConstraintRec *fc;
2849 Display *dpy;
2850 Window win;
2851 XSegment *topSeg, *botSeg;
2852 int i, st, botOff, tCount, bCount;
2853
2854 dpy = XtDisplay(f);
2855 win = XtWindow(f);
2856 fc = (XmLFolderConstraintRec *)(w->core.constraints);
2857 botOff =
2 * fc->folder.y + fc->folder.height -
1;
2858 st = f->manager.shadow_thickness;
2859 if (!st)
2860 return;
2861
2862 tCount =
0;
2863 bCount =
0;
2864 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
2865 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
2866 for (i =
0; i < st; i++)
2867 {
2868
2869 topSeg[tCount].x1 = fc->folder.x + i;
2870 topSeg[tCount].y1 = fc->folder.y + i;
2871 topSeg[tCount].x2 = fc->folder.x + i;
2872 topSeg[tCount].y2 = fc->folder.y + fc->folder.height -
1;
2873 if (w == f->folder.activeW)
2874 topSeg[tCount].y2 += i;
2875 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2876 {
2877 topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
2878 topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
2879 }
2880 tCount++;
2881
2882
2883 botSeg[bCount].x1 = fc->folder.x + fc->folder.width -
1 - i;
2884 botSeg[bCount].y1 = fc->folder.y + i;
2885 botSeg[bCount].x2 = fc->folder.x + fc->folder.width -
1 - i;
2886 botSeg[bCount].y2 = fc->folder.y + fc->folder.height -
1;
2887 if (w == f->folder.activeW)
2888 botSeg[bCount].y2 += i;
2889 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2890 {
2891 botSeg[bCount].y1 = botOff - botSeg[bCount].y1;
2892 botSeg[bCount].y2 = botOff - botSeg[bCount].y2;
2893 }
2894 bCount++;
2895 }
2896 if (tCount)
2897 {
2898 SetGC(f,
GC_SHADOWTOP);
2899 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2900 SetGC(f,
GC_UNSET);
2901 }
2902 if (bCount)
2903 {
2904 SetGC(f,
GC_SHADOWBOT);
2905 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2906 SetGC(f,
GC_UNSET);
2907 }
2908
2909 tCount =
0;
2910 for (i =
0; i < st; i++)
2911 {
2912
2913 topSeg[tCount].x1 = fc->folder.x + i +
1;
2914 topSeg[tCount].y1 = fc->folder.y + i;
2915 topSeg[tCount].x2 = fc->folder.x + fc->folder.width - i -
1;
2916 topSeg[tCount].y2 = fc->folder.y + i;
2917 if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
2918 {
2919 topSeg[tCount].y1 = botOff - topSeg[tCount].y1;
2920 topSeg[tCount].y2 = botOff - topSeg[tCount].y2;
2921 }
2922 tCount++;
2923 }
2924 if (tCount)
2925 {
2926 if (f->folder.tabPlacement == XmFOLDER_TOP)
2927 SetGC(f,
GC_SHADOWTOP);
2928 else
2929 SetGC(f,
GC_SHADOWBOT);
2930 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2931 SetGC(f,
GC_UNSET);
2932 }
2933 free((
char *)topSeg);
2934 free((
char *)botSeg);
2935 }
2936
2937 static void
2938 DrawTabShadowNoneLeftRight(XmLFolderWidget f,
2939 Widget w)
2940 {
2941 XmLFolderConstraintRec *fc;
2942 Display *dpy;
2943 Window win;
2944 XSegment *topSeg, *botSeg;
2945 int i, st, rightOff, tCount, bCount;
2946
2947 dpy = XtDisplay(f);
2948 win = XtWindow(f);
2949 fc = (XmLFolderConstraintRec *)(w->core.constraints);
2950 rightOff =
2 * fc->folder.x + fc->folder.width -
1;
2951 st = f->manager.shadow_thickness;
2952 if (!st)
2953 return;
2954
2955 tCount =
0;
2956 bCount =
0;
2957 topSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
2958 botSeg = (XSegment *)malloc(
sizeof(XSegment) * st *
2);
2959 for (i =
0; i < st; i++)
2960 {
2961
2962 topSeg[tCount].x1 = fc->folder.x + i;
2963 topSeg[tCount].y1 = fc->folder.y + i;
2964 topSeg[tCount].x2 = fc->folder.x + fc->folder.width -
1;
2965 if (w == f->folder.activeW)
2966 topSeg[tCount].x2 += i;
2967 topSeg[tCount].y2 = fc->folder.y + i;
2968 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2969 {
2970 topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
2971 topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
2972 }
2973 tCount++;
2974
2975
2976 botSeg[bCount].x1 = fc->folder.x + i;
2977 botSeg[bCount].y1 = fc->folder.y + fc->folder.height - i -
1;
2978 botSeg[bCount].x2 = fc->folder.x + fc->folder.width -
1;
2979 if (w == f->folder.activeW)
2980 botSeg[bCount].x2 += i;
2981 botSeg[bCount].y2 = fc->folder.y + fc->folder.height - i -
1;
2982 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
2983 {
2984 botSeg[bCount].x1 = rightOff - botSeg[bCount].x1;
2985 botSeg[bCount].x2 = rightOff - botSeg[bCount].x2;
2986 }
2987 bCount++;
2988 }
2989 if (tCount)
2990 {
2991 SetGC(f,
GC_SHADOWTOP);
2992 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
2993 SetGC(f,
GC_UNSET);
2994 }
2995 if (bCount)
2996 {
2997 SetGC(f,
GC_SHADOWBOT);
2998 XDrawSegments(dpy, win, f->folder.gc, botSeg, bCount);
2999 SetGC(f,
GC_UNSET);
3000 }
3001
3002 tCount =
0;
3003 for (i =
0; i < st; i++)
3004 {
3005
3006 topSeg[tCount].x1 = fc->folder.x + i;
3007 topSeg[tCount].y1 = fc->folder.y + i +
1;
3008 topSeg[tCount].x2 = fc->folder.x + i;
3009 topSeg[tCount].y2 = fc->folder.y + fc->folder.height - i -
1;
3010 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
3011 {
3012 topSeg[tCount].x1 = rightOff - topSeg[tCount].x1;
3013 topSeg[tCount].x2 = rightOff - topSeg[tCount].x2;
3014 }
3015 tCount++;
3016 }
3017 if (tCount)
3018 {
3019 if (f->folder.tabPlacement == XmFOLDER_RIGHT)
3020 SetGC(f,
GC_SHADOWBOT);
3021 else
3022 SetGC(f,
GC_SHADOWTOP);
3023 XDrawSegments(dpy, win, f->folder.gc, topSeg, tCount);
3024 SetGC(f,
GC_UNSET);
3025 }
3026 free((
char *)topSeg);
3027 free((
char *)botSeg);
3028 }
3029
3030 static void
3031 SetGC(XmLFolderWidget f,
3032 int type)
3033 {
3034 Display *dpy;
3035 XGCValues values;
3036 XtGCMask mask;
3037
3038 dpy = XtDisplay(f);
3039 if (type ==
GC_SHADOWBOT)
3040 {
3041 mask = GCForeground;
3042 values.foreground = f->manager.bottom_shadow_color;
3043 if (f->manager.bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
3044 {
3045 mask |= GCFillStyle | GCTile;
3046 values.fill_style = FillTiled;
3047 values.tile = f->manager.bottom_shadow_pixmap;
3048 }
3049 XChangeGC(dpy, f->folder.gc, mask, &values);
3050 }
3051 else if (type ==
GC_SHADOWTOP)
3052 {
3053 mask = GCForeground;
3054 values.foreground = f->manager.top_shadow_color;
3055 if (f->manager.top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)
3056 {
3057 mask |= GCFillStyle | GCTile;
3058 values.fill_style = FillTiled;
3059 values.tile = f->manager.top_shadow_pixmap;
3060 }
3061 XChangeGC(dpy, f->folder.gc, mask, &values);
3062 }
3063 else if (type ==
GC_BLANK)
3064 {
3065 mask = GCForeground;
3066 values.foreground = f->folder.blankBg;
3067 if (f->folder.blankPix != XmUNSPECIFIED_PIXMAP)
3068 {
3069 mask |= GCFillStyle | GCTile;
3070 values.fill_style = FillTiled;
3071 values.tile = f->folder.blankPix;
3072 }
3073 XChangeGC(dpy, f->folder.gc, mask, &values);
3074 }
3075 else
3076 {
3077 mask = GCFillStyle;
3078 values.fill_style = FillSolid;
3079 XChangeGC(dpy, f->folder.gc, mask, &values);
3080 }
3081 }
3082
3083 static void
3084 DrawTabHighlight(XmLFolderWidget f,
3085 Widget w)
3086 {
3087 Display *dpy;
3088 Window win;
3089 int ht;
3090
3091 if (!XtIsRealized(w))
3092 return;
3093 if (!f->core.visible)
3094 return;
3095 dpy = XtDisplay(f);
3096 win = XtWindow(f);
3097 ht = f->folder.highlightThickness;
3098 if (f->folder.focusW == w)
3099 XSetForeground(dpy, f->folder.gc, f->manager.highlight_color);
3100 else
3101 {
3102 if (f->folder.activeW == w)
3103 XSetForeground(dpy, f->folder.gc, f->core.background_pixel);
3104 else
3105 XSetForeground(dpy, f->folder.gc, f->folder.inactiveBg);
3106 }
3107 XFillRectangle(dpy, win, f->folder.gc,
3108 w->core.x - ht, w->core.y - ht,
3109 XtWidth(w) + w->core.border_width *
2 + ht *
2,
3110 XtHeight(w) + w->core.border_width *
2 + ht *
2);
3111 }
3112
3113 static void
3114 SetTabPlacement(XmLFolderWidget f,
3115 Widget tab)
3116 {
3117 if (!XmIsDrawnButton(tab))
3118 return;
3119 if (f->folder.allowRotate == True &&
3120 f->folder.tabPlacement == XmFOLDER_LEFT)
3121 XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_UP);
3122 else if (f->folder.allowRotate == True &&
3123 f->folder.tabPlacement == XmFOLDER_RIGHT)
3124 XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_DOWN);
3125 else
3126 XmLDrawnButtonSetType(tab, XmDRAWNB_STRING, XmDRAWNB_RIGHT);
3127 if (XtIsRealized(tab))
3128 XClearArea(XtDisplay(tab), XtWindow(tab),
0,
0,
0,
0, True);
3129 }
3130
3131 static void
3132 GetTabRect(XmLFolderWidget f,
3133 Widget tab,
3134 XRectangle *rect,
3135 int includeShadow)
3136 {
3137 XmLFolderConstraintRec *fc;
3138 int st;
3139
3140 st = f->manager.shadow_thickness;
3141 fc = (XmLFolderConstraintRec *)(tab->core.constraints);
3142 rect->x = fc->folder.x;
3143 rect->y = fc->folder.y;
3144 rect->width = fc->folder.width;
3145 rect->height = fc->folder.height;
3146 if (includeShadow)
3147 {
3148 if (f->folder.tabPlacement == XmFOLDER_TOP)
3149 rect->height += st;
3150 else if (f->folder.tabPlacement == XmFOLDER_BOTTOM)
3151 {
3152 rect->y -= st;
3153 rect->height += st;
3154 }
3155 else if (f->folder.tabPlacement == XmFOLDER_LEFT)
3156 rect->width += st;
3157 else
3158 {
3159 rect->x -= st;
3160 rect->width += st;
3161 }
3162 }
3163 }
3164
3165 static void
3166 SetActiveTab(XmLFolderWidget f,
3167 Widget w,
3168 XEvent *event,
3169 Boolean notify)
3170 {
3171 XmLFolderCallbackStruct cbs;
3172 XmLFolderConstraintRec *fc, *cfc;
3173 int i, j, pos;
3174 Display *dpy;
3175 Window win;
3176 Widget activeW, child, mw, managedW;
3177 WidgetList children;
3178 XRectangle rect;
3179 char *name, buf[
256];
3180
3181 win = (Window)
NULL;
3182
3183 if (f->folder.activeW == w)
3184 return;
3185 dpy =
0;
3186 if (XtIsRealized((Widget)f) && f->core.visible)
3187 {
3188 dpy = XtDisplay(f);
3189 win = XtWindow(f);
3190 }
3191
3192 pos = -
1;
3193 for (i =
0; i < f->folder.tabCount; i++)
3194 if (w == f->folder.tabs[i])
3195 pos = i;
3196
3197 cbs.allowActivate =
1;
3198 cbs.layoutNeeded =
0;
3199 if (notify == True)
3200 {
3201 if (f->folder.debugLevel)
3202 fprintf(stderr,
"XmLFolder: activated %d\n", pos);
3203 cbs.reason = XmCR_ACTIVATE;
3204 cbs.event = event;
3205 cbs.pos = pos;
3206 XtCallCallbackList((Widget)f, f->folder.activateCallback, &cbs);
3207 }
3208 if (!cbs.allowActivate)
3209 return;
3210
3211
3212 activeW = f->folder.activeW;
3213 if (activeW && dpy)
3214 {
3215 GetTabRect(f, activeW, &rect,
1);
3216 XClearArea(dpy, win, rect.x, rect.y, rect.width,
3217 rect.height, True);
3218 }
3219
3220 f->folder.activeTab = pos;
3221 f->folder.activeW = w;
3222 if (!w)
3223 return;
3224
3225
3226 PrimFocusIn(w,
NULL,
NULL,
NULL);
3227
3228
3229 if (f->folder.tabsPerRow)
3230 {
3231 fc = (XmLFolderConstraintRec *)(w->core.constraints);
3232 if (fc->folder.row != f->folder.activeRow)
3233 Layout(f, False);
3234 }
3235
3236
3237 children = f->composite.children;
3238 f->folder.allowLayout =
0;
3239 for (i =
0; i < f->composite.num_children; i++)
3240 {
3241 child = children[i];
3242 if (!XtIsSubclass(child, xmPrimitiveWidgetClass))
3243 continue;
3244 fc = (XmLFolderConstraintRec *)(child->core.constraints);
3245 managedW =
0;
3246 if (fc->folder.managedName)
3247 {
3248 for (j =
0; j < f->composite.num_children; j++)
3249 {
3250 mw = children[j];
3251 if (XtIsSubclass(mw, xmPrimitiveWidgetClass))
3252 continue;
3253 name = XtName(mw);
3254 if (name && !strcmp(name, fc->folder.managedName))
3255 managedW = mw;
3256 cfc = (XmLFolderConstraintRec *)(mw->core.constraints);
3257 name = cfc->folder.managedName;
3258 if (name && !strcmp(name, fc->folder.managedName))
3259 managedW = mw;
3260 }
3261 if (!managedW)
3262 {
3263 sprintf(buf,
"SetActiveTab() - managed widget named ");
3264 strcat(buf, fc->folder.managedName);
3265 strcat(buf,
" not found");
3266 XmLWarning(child, buf);
3267 }
3268 }
3269 else
3270 managedW = fc->folder.managedW;
3271 if (managedW)
3272 {
3273 if (w == child && !XtIsManaged(managedW))
3274 XtManageChild(managedW);
3275 if (w != child && XtIsManaged(managedW))
3276 XtUnmanageChild(managedW);
3277 }
3278 }
3279 f->folder.allowLayout =
1;
3280
3281
3282 if (dpy)
3283 {
3284 GetTabRect(f, w, &rect,
1);
3285 XClearArea(dpy, win, rect.x, rect.y, rect.width, rect.height, True);
3286 XmProcessTraversal(w, XmTRAVERSE_CURRENT);
3287 }
3288
3289 if (cbs.layoutNeeded)
3290 Layout(f,
0);
3291 }
3292
3293
3294
3295
3296
3297 static void
3298 GetCoreBackground(Widget w,
3299 int offset,
3300 XrmValue *value)
3301 {
3302 value->addr = (
caddr_t)&w->core.background_pixel;
3303 }
3304
3305 static void
3306 GetDefaultTabWidgetClass(Widget w,
3307 int offset,
3308 XrmValue *value)
3309 {
3310 value->addr = (
caddr_t)&xmDrawnButtonWidgetClass;
3311 }
3312
3313 static void
3314 GetManagerForeground(Widget w,
3315 int offset,
3316 XrmValue *value)
3317 {
3318 XmLFolderWidget f;
3319
3320 f = (XmLFolderWidget)w;
3321 value->addr = (
caddr_t)&f->manager.foreground;
3322 }
3323
3324 static Boolean
3325 ServerDrawsArcsLarge(Display *dpy,
3326 int debug)
3327 {
3328 Pixmap pixmap;
3329 XImage *image;
3330 Window root;
3331 long pixel;
3332 int x, y, width, height, result;
3333 GC gc;
3334
3335 root = DefaultRootWindow(dpy);
3336 width =
5;
3337 height =
5;
3338 pixmap = XCreatePixmap(dpy, root, width, height,
1);
3339 gc = XCreateGC(dpy, pixmap,
0L,
NULL);
3340 XSetForeground(dpy, gc,
0L);
3341 XFillRectangle(dpy, pixmap, gc,
0,
0, width, height);
3342 XSetForeground(dpy, gc,
1L);
3343 XDrawArc(dpy, pixmap, gc,
0,
0, width, height,
0,
360 *
64);
3344 image = XGetImage(dpy, pixmap,
0,
0, width, height, AllPlanes, ZPixmap);
3345 if (debug)
3346 {
3347 fprintf(stderr,
"Test X server drawn arc (%d by %d):\n",
3348 width, height);
3349 for (y =
0; y < height; y++)
3350 {
3351 fprintf(stderr,
" ");
3352 for (x =
0; x < width; x++)
3353 {
3354 pixel = XGetPixel(image, x, y);
3355 if (pixel ==
0L)
3356 fprintf(stderr,
".");
3357 else
3358 fprintf(stderr,
"X");
3359 }
3360 fprintf(stderr,
"\n");
3361 }
3362 }
3363 if (XGetPixel(image, width -
1, height /
2) !=
1L)
3364 {
3365 result =
1;
3366 if (debug)
3367 fprintf(stderr,
"X Server Draws Arcs 1 Pixel Large\n");
3368 }
3369 else
3370 {
3371 result =
0;
3372 if (debug)
3373 fprintf(stderr,
"X Server Draws Arcs Within Bounds\n");
3374 }
3375 XDestroyImage(image);
3376 XFreeGC(dpy, gc);
3377 XFreePixmap(dpy, pixmap);
3378 return result;
3379 }
3380
3381
3382
3383
3384
3385 static Boolean
3386 SetValues(Widget curW,
3387 Widget reqW,
3388 Widget newW,
3389 ArgList args,
3390 Cardinal *narg)
3391 {
3392 XmLFolderWidget f;
3393 XmLFolderWidget cur;
3394 int i;
3395 Boolean needsLayout, needsRedisplay;
3396
3397 f = (XmLFolderWidget)newW;
3398 cur = (XmLFolderWidget)curW;
3399 needsLayout = False;
3400 needsRedisplay = False;
3401 #define NE(value) (f->value != cur->value)
3402 if (
NE(folder.tabBarHeight))
3403 {
3404 XmLWarning((Widget)f,
"SetValues() - can''t set tabBarHeight");
3405 f->folder.tabBarHeight = cur->folder.tabBarHeight;
3406 }
3407 if (
NE(folder.tabCount))
3408 {
3409 XmLWarning((Widget)f,
"SetValues() - can''t set tabCount");
3410 f->folder.tabCount = cur->folder.tabCount;
3411 }
3412 if (
NE(folder.activeTab))
3413 {
3414 XmLWarning((Widget)f,
"SetValues() - can''t set activeTab");
3415 f->folder.activeTab = cur->folder.activeTab;
3416 }
3417 if (f->folder.cornerDimension <
1)
3418 {
3419 XmLWarning((Widget)f,
"SetValues() - cornerDimension can''t be < 1");
3420 f->folder.cornerDimension = cur->folder.cornerDimension;
3421 }
3422 if (
NE(folder.tabPlacement) ||
3423 NE(folder.allowRotate))
3424 {
3425 f->folder.allowLayout =
0;
3426 for (i =
0; i < f->folder.tabCount; i++)
3427 SetTabPlacement(f, f->folder.tabs[i]);
3428 f->folder.allowLayout =
1;
3429 needsLayout = True;
3430 }
3431 if (
NE(folder.inactiveBg) ||
3432 NE(folder.blankBg) ||
3433 NE(folder.blankPix) ||
3434 NE(folder.inactiveFg))
3435 needsRedisplay = True;
3436 if (
NE(folder.cornerDimension) ||
3437 NE(folder.cornerStyle) ||
3438 NE(folder.highlightThickness) ||
3439 NE(folder.marginHeight) ||
3440 NE(folder.marginWidth) ||
3441 NE(folder.pixmapMargin) ||
3442 NE(manager.shadow_thickness) ||
3443 NE(folder.tabsPerRow) ||
3444 NE(folder.spacing))
3445 needsLayout = True;
3446 if (
NE(folder.renderTable))
3447 {
3448 XmRenderTableFree(cur->folder.renderTable);
3449 CopyRenderTable(f);
3450 }
3451 #undef NE
3452 if (needsLayout == True)
3453 Layout(f,
1);
3454 return needsRedisplay;
3455 }
3456
3457 static void
3458 CopyRenderTable(XmLFolderWidget f)
3459 {
3460 if (!f->folder.renderTable)
3461 f->folder.renderTable = XmLRenderTableCopyDefault((Widget)f);
3462 else
3463 f->folder.renderTable = XmRenderTableCopy(f->folder.renderTable,
NULL,
0);
3464 if (!f->folder.renderTable)
3465 XmLWarning((Widget)f,
"- fatal error - font list NULL");
3466 }
3467
3468 static Boolean
3469 ConstraintSetValues(Widget curW,
3470 Widget reqW,
3471 Widget newW,
3472 ArgList args,
3473 Cardinal *narg)
3474 {
3475 XmLFolderConstraintRec *cons, *curCons;
3476 XmLFolderWidget f;
3477 int i, hasLabelChange;
3478
3479 f = (XmLFolderWidget)XtParent(newW);
3480 if (!XtIsRectObj(newW))
3481 return False;
3482 cons = (XmLFolderConstraintRec *)newW->core.constraints;
3483 curCons = (XmLFolderConstraintRec *)curW->core.constraints;
3484 #define NE(value) (cons->value != curCons->value)
3485 if (
NE(folder.managedName))
3486 {
3487 if (curCons->folder.managedName)
3488 free((
char *)curCons->folder.managedName);
3489 if (cons->folder.managedName)
3490 cons->folder.managedName = (
char *)strdup(cons->folder.managedName);
3491 }
3492 #undef NE
3493 hasLabelChange =
0;
3494 if (XtIsSubclass(newW, xmPrimitiveWidgetClass))
3495 {
3496 for (i =
0; i < *narg; i++)
3497 if (args[i].name && !strcmp(args[i].name, XmNlabelString))
3498 hasLabelChange =
1;
3499 if (hasLabelChange &&
3500 (f->folder.tabPlacement == XmFOLDER_LEFT ||
3501 f->folder.tabPlacement == XmFOLDER_RIGHT))
3502 {
3503 f->folder.allowLayout =
0;
3504 for (i =
0; i < f->folder.tabCount; i++)
3505 SetTabPlacement(f, f->folder.tabs[i]);
3506 f->folder.allowLayout =
1;
3507 }
3508 }
3509 if (hasLabelChange ||
3510 curCons->folder.pix != cons->folder.pix ||
3511 curCons->folder.inactPix != cons->folder.inactPix)
3512 Layout((XmLFolderWidget)XtParent(curW),
1);
3513 return False;
3514 }
3515
3516 static Boolean
3517 CvtStringToCornerStyle(Display *dpy,
3518 XrmValuePtr args,
3519 Cardinal *narg,
3520 XrmValuePtr fromVal,
3521 XrmValuePtr toVal,
3522 XtPointer *data)
3523 {
3524 static XmLStringToUCharMap map[] =
3525 {
3526 {
"CORNER_NONE", XmCORNER_NONE },
3527 {
"CORNER_LINE", XmCORNER_LINE },
3528 {
"CORNER_ARC", XmCORNER_ARC },
3529 {
0,
0 },
3530 };
3531
3532 return XmLCvtStringToUChar(dpy,
"XmRCornerStyle", map, fromVal, toVal);
3533 }
3534
3535 static Boolean
3536 CvtStringToFolderResizePolicy(Display *dpy,
3537 XrmValuePtr args,
3538 Cardinal *narg,
3539 XrmValuePtr fromVal,
3540 XrmValuePtr toVal,
3541 XtPointer *data)
3542 {
3543 static XmLStringToUCharMap map[] =
3544 {
3545 {
"RESIZE_NONE", XmRESIZE_NONE },
3546 {
"RESIZE_STATIC", XmRESIZE_STATIC },
3547 {
"RESIZE_DYNAMIC", XmRESIZE_DYNAMIC },
3548 {
"RESIZE_PACK", XmRESIZE_PACK },
3549 {
0,
0 },
3550 };
3551
3552 return XmLCvtStringToUChar(dpy,
"XmRFolderResizePolicy", map,
3553 fromVal, toVal);
3554 }
3555
3556 static Boolean
3557 CvtStringToTabPlacement(Display *dpy,
3558 XrmValuePtr args,
3559 Cardinal *narg,
3560 XrmValuePtr fromVal,
3561 XrmValuePtr toVal,
3562 XtPointer *data)
3563 {
3564 static XmLStringToUCharMap map[] =
3565 {
3566 {
"FOLDER_TOP", XmFOLDER_TOP },
3567 {
"FOLDER_LEFT", XmFOLDER_LEFT },
3568 {
"FOLDER_BOTTOM", XmFOLDER_BOTTOM },
3569 {
"FOLDER_RIGHT", XmFOLDER_RIGHT },
3570 {
0,
0 },
3571 };
3572
3573 return XmLCvtStringToUChar(dpy,
"XmRTabPlacement", map, fromVal, toVal);
3574 }
3575
3576
3577
3578
3579
3580 static void
3581 Activate(Widget w,
3582 XEvent *event,
3583 String *params,
3584 Cardinal *nparam)
3585 {
3586 XmLFolderWidget f;
3587 XButtonEvent *be;
3588 XRectangle rect;
3589 Widget tab;
3590 int i;
3591
3592 f = (XmLFolderWidget)w;
3593 if (!event || event->type != ButtonPress)
3594 return;
3595 be = (XButtonEvent *)event;
3596 if (f->folder.debugLevel)
3597 fprintf(stderr,
"XmLFolder: ButtonPress %d %d\n", be->x, be->y);
3598 for (i =
0; i < f->folder.tabCount; i++)
3599 {
3600 tab = f->folder.tabs[i];
3601 if (!XtIsManaged(tab) || !XtIsSensitive(tab))
3602 continue;
3603 GetTabRect(f, tab, &rect,
0);
3604 if (be->x > rect.x && be->x < rect.x + (
int)rect.width &&
3605 be->y > rect.y && be->y < rect.y + (
int)rect.height)
3606 {
3607 if (f->folder.debugLevel)
3608 fprintf(stderr,
"XmLFolder: Pressed tab %d\n", i);
3609 SetActiveTab(f, tab, event, True);
3610 return;
3611 }
3612 }
3613 }
3614
3615 static void
3616 PrimActivate(Widget w,
3617 XtPointer clientData,
3618 XtPointer callData)
3619 {
3620 XmLFolderWidget f;
3621 XmAnyCallbackStruct *cbs;
3622
3623 f = (XmLFolderWidget)XtParent(w);
3624 cbs = (XmAnyCallbackStruct *)callData;
3625 SetActiveTab(f, w, cbs->event, True);
3626 }
3627
3628 static void
3629 PrimFocusIn(Widget w,
3630 XEvent *event,
3631 String *params,
3632 Cardinal *nparam)
3633 {
3634 XmLFolderWidget f;
3635 Widget prevW;
3636
3637 f = (XmLFolderWidget)XtParent(w);
3638 prevW = f->folder.focusW;
3639 f->folder.focusW = w;
3640 DrawTabHighlight(f, w);
3641 if (prevW)
3642 DrawTabHighlight(f, prevW);
3643 XmProcessTraversal(w, XmTRAVERSE_CURRENT);
3644 }
3645
3646 static void
3647 PrimFocusOut(Widget w,
3648 XEvent *event,
3649 String *params,
3650 Cardinal *nparam)
3651 {
3652 XmLFolderWidget f;
3653 Widget prevW;
3654
3655 f = (XmLFolderWidget)XtParent(w);
3656 prevW = f->folder.focusW;
3657 f->folder.focusW =
0;
3658 if (prevW)
3659 DrawTabHighlight(f, prevW);
3660 DrawTabHighlight(f, w);
3661 }
3662
3663
3664
3665
3666
3667 Widget
3668 XmLCreateFolder(Widget parent,
3669 char *name,
3670 ArgList arglist,
3671 Cardinal argcount)
3672 {
3673 return XtCreateWidget(name, xmlFolderWidgetClass, parent,
3674 arglist, argcount);
3675 }
3676
3677 Widget
3678 XmLFolderAddBitmapTab(Widget w,
3679 XmString string,
3680 char *bitmapBits,
3681 int bitmapWidth,
3682 int bitmapHeight)
3683 {
3684 XmLFolderWidget f;
3685 Widget tab;
3686 Pixmap pix, inactPix;
3687 Window root;
3688 Display *dpy;
3689 int depth;
3690 char name[
20];
3691
3692 if (!XmLIsFolder(w))
3693 {
3694 XmLWarning(w,
"AddBitmapTab() - widget not a XmLFolder");
3695 return 0;
3696 }
3697 f = (XmLFolderWidget)w;
3698 dpy = XtDisplay(w);
3699 root = DefaultRootWindow(dpy);
3700 depth = DefaultDepthOfScreen(XtScreen(w));
3701 pix = XCreatePixmapFromBitmapData(dpy, root, bitmapBits,
3702 bitmapWidth, bitmapHeight, f->manager.foreground,
3703 f->core.background_pixel, depth);
3704 inactPix = XCreatePixmapFromBitmapData(dpy, root, bitmapBits,
3705 bitmapWidth, bitmapHeight, f->folder.inactiveFg,
3706 f->folder.inactiveBg, depth);
3707 sprintf(name,
"tab%d", f->folder.tabCount);
3708 tab = XtVaCreateManagedWidget(name,
3709 f->folder.tabWidgetClass, w,
3710 XmNrenderTable, f->folder.renderTable,
3711 XmNmarginWidth,
0,
3712 XmNmarginHeight,
0,
3713 XmNlabelString, string,
3714 XmNtabPixmap, pix,
3715 XmNtabInactivePixmap, inactPix,
3716 XmNtabFreePixmaps, True,
3717 NULL);
3718 return tab;
3719 }
3720
3721 Widget
3722 XmLFolderAddBitmapTabForm(Widget w,
3723 XmString string,
3724 char *bitmapBits,
3725 int bitmapWidth,
3726 int bitmapHeight)
3727 {
3728 Widget form, tab;
3729 XmLFolderWidget f;
3730 char name[
20];
3731
3732 if (!XmLIsFolder(w))
3733 {
3734 XmLWarning(w,
"AddBitmapTabForm() - widget not a XmLFolder");
3735 return 0;
3736 }
3737 f = (XmLFolderWidget)w;
3738 tab = XmLFolderAddBitmapTab(w, string, bitmapBits,
3739 bitmapWidth, bitmapHeight);
3740 sprintf(name,
"form%d", f->folder.tabCount);
3741 form = XtVaCreateManagedWidget(name,
3742 xmFormWidgetClass, w,
3743 XmNbackground, f->core.background_pixel,
3744 NULL);
3745 XtVaSetValues(tab, XmNtabManagedWidget, form,
NULL);
3746 return form;
3747 }
3748
3749 Widget
3750 XmLFolderAddTab(Widget w,
3751 XmString string)
3752 {
3753 Widget tab;
3754 XmLFolderWidget f;
3755 char name[
20];
3756
3757 if (!XmLIsFolder(w))
3758 {
3759 XmLWarning(w,
"AddTab() - widget not a XmLFolder");
3760 return 0;
3761 }
3762 f = (XmLFolderWidget)w;
3763 sprintf(name,
"tab%d", f->folder.tabCount);
3764 tab = XtVaCreateManagedWidget(name,
3765 f->folder.tabWidgetClass, w,
3766 XmNrenderTable, f->folder.renderTable,
3767 XmNmarginWidth,
0,
3768 XmNmarginHeight,
0,
3769 XmNlabelString, string,
3770 NULL);
3771 return tab;
3772 }
3773
3774 Widget
3775 XmLFolderAddTabFromClass(Widget w,
3776 XmString string)
3777 {
3778 Widget tab;
3779 XmLFolderWidget f;
3780 char name[
20];
3781
3782 if (!XmLIsFolder(w))
3783 {
3784 XmLWarning(w,
"AddTab() - widget not a XmLFolder");
3785 return 0;
3786 }
3787 f = (XmLFolderWidget)w;
3788 sprintf(name,
"tab%d", f->folder.tabCount);
3789
3790 tab = XtVaCreateManagedWidget(name,
3791 f->folder.tabWidgetClass,
3792
3793 w,
3794 XmNrenderTable, f->folder.renderTable,
3795
3796
3797 XmNlabelString, string,
3798 NULL);
3799 return tab;
3800 }
3801
3802 Widget
3803 XmLFolderAddTabForm(Widget w,
3804 XmString string)
3805 {
3806 Widget form, tab;
3807 XmLFolderWidget f;
3808 char name[
20];
3809
3810 if (!XmLIsFolder(w))
3811 {
3812 XmLWarning(w,
"AddBitmapTabForm() - widget not a XmLFolder");
3813 return 0;
3814 }
3815 f = (XmLFolderWidget)w;
3816 tab = XmLFolderAddTab(w, string);
3817 sprintf(name,
"form%d", f->folder.tabCount);
3818 form = XtVaCreateManagedWidget(name,
3819 xmFormWidgetClass, w,
3820 XmNbackground, f->core.background_pixel,
3821 NULL);
3822 XtVaSetValues(tab, XmNtabManagedWidget, form,
NULL);
3823 return form;
3824 }
3825
3826 void
3827 XmLFolderSetActiveTab(Widget w,
3828 int position,
3829 Boolean notify)
3830 {
3831 XmLFolderWidget f;
3832
3833 if (!XmLIsFolder(w))
3834 {
3835 XmLWarning(w,
"SetActiveTab() - widget not a XmLFolder");
3836 return;
3837 }
3838 f = (XmLFolderWidget)w;
3839 if (position <
0 || position >= f->folder.tabCount)
3840 {
3841 XmLWarning(w,
"SetActiveTab() - invalid position");
3842 return;
3843 }
3844 SetActiveTab(f, f->folder.tabs[position],
0, notify);
3845 }
3846