2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* helper functions */
22 /* get byte offset corresponding to character offset, including
23 bounds check to represent end of text */
24 int getByteOffsetBoundsCheck(FlocaleFont
*flf
, char *str
, int offset
)
26 if(offset
< FlocaleStringCharLength(flf
,str
))
27 return FlocaleStringCharToByteOffset(flf
, str
, offset
);
32 /* opposite of the above, return character offset */
33 int getCharOffsetBoundsCheck(FlocaleFont
*flf
, char *str
, int offset
)
35 if(offset
< strlen(str
))
36 return FlocaleStringByteToCharOffset(flf
, str
, offset
);
38 return FlocaleStringCharLength(flf
, str
);
42 * Fonction d'ecriture en relief
45 Display
*dpy
, struct XObj
*xobj
, Window win
, int x
, int y
,
46 char *str
, unsigned long ForeC
,unsigned long HiC
,
47 unsigned long BackC
, int WithRelief
, XRectangle
*clip
, XEvent
*evp
)
55 if (!frect_get_intersection(
56 clip
->x
, clip
->y
, clip
->width
, clip
->height
,
57 evp
->xexpose
.x
, evp
->xexpose
.y
,
58 evp
->xexpose
.width
, evp
->xexpose
.height
,
68 inter
.width
= clip
->width
;
69 inter
.height
= clip
->height
;
73 inter
.x
= evp
->xexpose
.x
;
74 inter
.y
= evp
->xexpose
.y
;
75 inter
.width
= evp
->xexpose
.width
;
76 inter
.height
= evp
->xexpose
.height
;
84 region
= XCreateRegion();
85 XUnionRectWithRegion (&inter
, region
, region
);
86 XSetClipRectangles(dpy
, xobj
->gc
, 0, 0, &inter
, 1, Unsorted
);
87 FwinString
->flags
.has_clip_region
= True
;
88 FwinString
->clip_region
= region
;
92 FwinString
->flags
.has_clip_region
= False
;
95 FwinString
->win
= win
;
96 FwinString
->str
= str
;
97 FwinString
->gc
= xobj
->gc
;
98 FwinString
->flags
.has_colorset
= False
;
99 if (xobj
->colorset
>= 0)
101 FwinString
->colorset
= &Colorset
[xobj
->colorset
];
102 FwinString
->flags
.has_colorset
= True
;
104 if (WithRelief
&& xobj
->Ffont
->shadow_size
== 0)
106 XSetBackground(dpy
, xobj
->gc
, xobj
->TabColor
[BackC
]);
107 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[HiC
]);
110 FlocaleDrawString(dpy
, xobj
->Ffont
, FwinString
, 0);
111 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[ForeC
]);
114 FlocaleDrawString(dpy
, xobj
->Ffont
, FwinString
, 0);
118 XSetBackground(dpy
, xobj
->gc
, xobj
->TabColor
[BackC
]);
119 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[ForeC
]);
122 FlocaleDrawString(dpy
, xobj
->Ffont
, FwinString
, 0);
126 XDestroyRegion(region
);
127 XSetClipMask(dpy
, xobj
->gc
, None
);
129 FwinString
->flags
.has_clip_region
= False
;
133 * Return the x text position of the widget
135 int GetXTextPosition(struct XObj
*xobj
, int obj_width
, int str_len
,
136 int left_offset
, int center_offset
, int right_offset
)
141 if (!IS_TEXT_POS_DEFAULT(xobj
))
143 position
= GET_TEXT_POS(xobj
);
147 switch (xobj
->TypeWidget
)
151 position
= TEXT_POS_CENTER
;
154 position
= TEXT_POS_LEFT
;
159 if (position
== TEXT_POS_CENTER
)
161 x
= (obj_width
- str_len
)/2 + center_offset
;
163 else if (position
== TEXT_POS_LEFT
)
167 else /* position == TEXT_POS_RIGHT */
169 x
= (obj_width
- str_len
) - right_offset
;
175 * Retourne le titre de l'option id du menu
177 char* GetMenuTitle(char *str
, int id
)
184 while ((str
[w
+w2
] != '\0') && (str
[w
+w2
] != '|'))
187 while ((i
< id
) && (str
[w
] != '\0'))
190 if (str
[w
+w2
] == '|')
194 while ((str
[w
+w2
] != '\0') && (str
[w
+w2
] != '|'))
197 TempStr
= (char*)calloc(sizeof(char),w2
+1);
198 TempStr
= strncpy(TempStr
,&str
[w
],w2
);
203 * Dessine le contenu de la fenetre du popup-menu
205 void DrawPMenu(struct XObj
*xobj
, Window WinPop
, int h
, int StrtOpt
)
210 unsigned int width
,height
;
213 if (!XGetGeometry(dpy
, WinPop
, &Root
, &x
, &y
, &width
, &height
, &i
, &i
))
219 segm
[0].x2
= width
-i
-1;
225 segm
[1].y2
= height
-i
-1;
226 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
227 XDrawSegments(dpy
, WinPop
, xobj
->gc
, segm
, 2);
230 segm
[0].y1
= height
-i
-1;
231 segm
[0].x2
= width
-i
-1;
232 segm
[0].y2
= height
-i
-1;
234 segm
[1].x1
= width
-i
-1;
236 segm
[1].x2
= width
-i
-1;
237 segm
[1].y2
= height
-i
-1;
238 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
239 XDrawSegments(dpy
, WinPop
, xobj
->gc
, segm
, 2);
241 /* Ecriture des options */
242 for (i
=StrtOpt
; i
<= xobj
->value3
; i
++)
244 xobj
, WinPop
, h
, i
, width
, xobj
->Ffont
->ascent
, StrtOpt
);
247 void UnselectMenu(struct XObj
*xobj
, Window WinPop
, int hOpt
, int value
,
248 unsigned int width
, int asc
, int start
)
253 y
= hOpt
* (value
- 1);
254 XClearArea(dpy
, WinPop
, 2, y
+ 2, width
- 4, hOpt
- 4, False
);
255 str
= (char*)GetMenuTitle(xobj
->title
, value
+ start
);
258 x
= GetXTextPosition(xobj
, width
, FlocaleTextWidth(xobj
->Ffont
,str
,len
),
260 MyDrawString(dpy
, xobj
, WinPop
, x
, y
, str
, fore
, hili
, back
,
261 !xobj
->flags
[1], NULL
, NULL
);
266 * Dessine l'option active d'un menu
268 void SelectMenu(struct XObj
*xobj
, Window WinPop
, int hOpt
, int value
)
273 unsigned int width
,height
;
276 if (!XGetGeometry(dpy
, WinPop
, &Root
, &x
, &y
, &width
, &height
, &i
, &i
))
283 segm
[0].x2
= width
-i
-3;
289 segm
[1].y2
= y
+hOpt
-4-i
;
290 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
291 XDrawSegments(dpy
, WinPop
, xobj
->gc
, segm
, 2);
294 segm
[0].y1
= y
-i
-3+hOpt
;
295 segm
[0].x2
= width
-i
-3;
296 segm
[0].y2
= y
-i
-3+hOpt
;
298 segm
[1].x1
= width
-i
-3;
300 segm
[1].x2
= width
-i
-3;
301 segm
[1].y2
= i
+y
-4+hOpt
;
302 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
303 XDrawSegments(dpy
, WinPop
, xobj
->gc
, segm
, 2);
308 * Compte le nombre d'option contenu dans un menu
310 int CountOption(char *str
)
315 while (str
[w
] != '\0')
317 if (str
[w
] == '|') i
++;
326 * Dessine l'icone et le titre du widget
329 int offset
, struct XObj
*xobj
, int DoRedraw
,
330 int l_offset
, int c_offset
, int r_offset
,
331 XRectangle
*str_clip
, XRectangle
*icon_clip
, XEvent
*evp
)
336 XRectangle clear_r
, inter
;
337 Bool do_clear
= True
;
339 inter
.x
= clear_r
.x
= 4;
340 inter
.y
= clear_r
.y
= 4;
341 inter
.width
= clear_r
.width
= xobj
->width
-8;
342 inter
.height
= clear_r
.height
= xobj
->height
-8;
346 if (!frect_get_intersection(
347 clear_r
.x
, clear_r
.y
, clear_r
.width
,
348 clear_r
.height
, evp
->xexpose
.x
, evp
->xexpose
.y
,
349 evp
->xexpose
.width
, evp
->xexpose
.height
,
360 inter
.width
= clip
->width
;
361 inter
.height
= clip
->height
;
365 inter
.x
= evp
->xexpose
.x
;
366 inter
.y
= evp
->xexpose
.y
;
367 inter
.width
= evp
->xexpose
.width
;
368 inter
.height
= evp
->xexpose
.height
;
371 if (DoRedraw
&& do_clear
)
375 inter
.x
, inter
.y
, inter
.width
, inter
.height
, False
);
378 str
= GetMenuTitle(xobj
->title
,1);
380 i
= GetXTextPosition(
381 xobj
, xobj
->width
, FlocaleTextWidth(xobj
->Ffont
,str
,len
),
382 l_offset
, c_offset
, r_offset
);
384 if (len
> 0 && xobj
->iconPixmap
==None
)
386 /* Si l'icone n'existe pas */
387 j
= xobj
->height
/2 - (xobj
->Ffont
->height
)/2 +
388 xobj
->Ffont
->ascent
+ offset
;
390 dpy
,xobj
,xobj
->win
,i
,j
,str
,fore
,hili
,back
,
391 !xobj
->flags
[1], str_clip
, evp
);
395 /* Si l'icone existe */
396 FvwmRenderAttributes fra
;
397 Bool do_draw_icon
= True
;
399 int iy
= (xobj
->height
- xobj
->icon_h
)/2+offset
;
400 int ix
= (xobj
->width
- xobj
->icon_w
)/2+offset
;
402 if (evp
&& icon_clip
)
404 if (!frect_get_intersection(
405 icon_clip
->x
, icon_clip
->y
,
406 icon_clip
->width
, icon_clip
->height
,
407 evp
->xexpose
.x
, evp
->xexpose
.y
,
408 evp
->xexpose
.width
, evp
->xexpose
.height
,
411 do_draw_icon
= False
;
413 else if (!frect_get_intersection(
415 inter
.width
, inter
.height
,
416 ix
, iy
, xobj
->icon_w
, xobj
->icon_h
,
419 do_draw_icon
= False
;
424 if (!frect_get_intersection(
425 icon_clip
->x
, icon_clip
->y
,
426 icon_clip
->width
, icon_clip
->height
,
427 ix
, iy
, xobj
->icon_w
, xobj
->icon_h
,
430 do_draw_icon
= False
;
435 if (!frect_get_intersection(
436 evp
->xexpose
.x
, evp
->xexpose
.y
,
437 evp
->xexpose
.width
, evp
->xexpose
.height
,
438 ix
, iy
, xobj
->icon_w
, xobj
->icon_h
,
441 do_draw_icon
= False
;
448 ir
.width
= xobj
->icon_w
;
449 ir
.height
= xobj
->icon_h
;
454 j
= ((xobj
->height
- xobj
->icon_h
)/4)*3 +
455 xobj
->icon_h
+ offset
+ xobj
->Ffont
->ascent
;
457 dpy
,xobj
,xobj
->win
,i
,j
,str
,fore
,hili
,
458 back
,!xobj
->flags
[1], str_clip
, evp
);
460 /* Dessin de l'icone */
461 fra
.mask
= FRAM_DEST_IS_A_WINDOW
;
462 if (xobj
->colorset
>= 0)
464 fra
.mask
|= FRAM_HAVE_ICON_CSET
;
465 fra
.colorset
= &Colorset
[xobj
->colorset
];
469 PGraphicsRenderPixmaps(
470 dpy
, xobj
->win
, xobj
->iconPixmap
,
471 xobj
->icon_maskPixmap
, xobj
->icon_alphaPixmap
,
472 Pdepth
, &fra
, xobj
->win
, xobj
->gc
, None
, None
,
473 ir
.x
- ix
, ir
.y
- iy
, ir
.width
, ir
.height
,
474 ir
.x
, ir
.y
, ir
.width
, ir
.height
, False
);
481 * Fonction de dessin d'un rectangle en relief
483 void DrawReliefRect(int x
, int y
, int width
, int height
, struct XObj
*xobj
,
484 unsigned int LiC
, unsigned int ShadC
)
499 segm
[0].y2
= height
+j
+y
+1;
502 segm
[1].x2
= width
+j
+x
+1;
504 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[LiC
]);
505 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 2);
507 segm
[0].x1
= width
+j
+x
+1;
509 segm
[0].x2
= width
+j
+x
+1;
510 segm
[0].y2
= height
+j
+y
+1;
512 segm
[1].y1
= height
+j
+y
+1;
513 segm
[1].x2
= width
+j
+x
+1;
514 segm
[1].y2
= height
+j
+y
+1;
515 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[ShadC
]);
516 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 2);
518 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[fore
]);
522 * Insertion d'un str dans le titre d'un objet
524 int InsertText(struct XObj
*xobj
, char *str
, int SizeStr
)
530 /* Insertion du caractere dans le titre */
531 NewPos
= getByteOffsetBoundsCheck(xobj
->Ffont
, xobj
->title
,
533 Size
= strlen(xobj
->title
);
534 xobj
->title
= (char*)realloc(
535 xobj
->title
, (1+SizeStr
+Size
)*sizeof(char));
536 memmove(&xobj
->title
[NewPos
+SizeStr
], &xobj
->title
[NewPos
],
538 for (i
=NewPos
; i
< NewPos
+SizeStr
; i
++)
539 xobj
->title
[i
] = str
[i
-NewPos
];
540 NewPos
= NewPos
+SizeStr
;
541 return getCharOffsetBoundsCheck(xobj
->Ffont
, xobj
->title
, NewPos
);
545 * Lecture d'un morceau de texte de xobj->value à End
547 char *GetText(struct XObj
*xobj
, int End
)
552 if (End
> xobj
->value
)
554 a
= getByteOffsetBoundsCheck(xobj
->Ffont
, xobj
->title
,
556 b
= getByteOffsetBoundsCheck(xobj
->Ffont
, xobj
->title
,
561 b
= getByteOffsetBoundsCheck(xobj
->Ffont
, xobj
->title
,
563 a
= getByteOffsetBoundsCheck(xobj
->Ffont
, xobj
->title
,
566 str
= (char*)calloc(b
-a
+2,1);
567 memcpy(str
, &xobj
->title
[a
], b
-a
);
572 void UnselectAllTextField(struct XObj
**txobj
)
576 for (i
=0; i
<nbobj
; i
++)
578 if (txobj
[i
]->TypeWidget
== TextField
)
580 if (txobj
[i
]->value2
!= txobj
[i
]->value
)
582 txobj
[i
]->value2
= txobj
[i
]->value
;
583 txobj
[i
]->DrawObj(txobj
[i
],NULL
);
590 void SelectOneTextField(struct XObj
*xobj
)
594 for (i
=0; i
<nbobj
; i
++)
596 if ((tabxobj
[i
]->TypeWidget
== TextField
) &&
597 (xobj
!= tabxobj
[i
]))
599 if (tabxobj
[i
]->value2
!= tabxobj
[i
]->value
)
601 tabxobj
[i
]->value2
= tabxobj
[i
]->value
;
602 tabxobj
[i
]->DrawObj(tabxobj
[i
],NULL
);
610 * Dessine une fleche direction nord
612 void DrawArrowN(struct XObj
*xobj
, int x
, int y
, int Press
)
625 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
627 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
628 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 2);
648 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
650 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
651 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 4);
655 * Dessine une fleche direction sud
657 void DrawArrowS(struct XObj
*xobj
, int x
, int y
, int Press
)
679 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
681 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
682 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 4);
693 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
695 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
696 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 2);
699 void DrawArrowE(struct XObj
*xobj
, int x
, int y
, int Press
)
712 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
714 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
715 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 2);
735 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
737 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
738 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 4);
741 void DrawArrowW(struct XObj
*xobj
, int x
, int y
, int Press
)
754 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
756 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
757 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 2);
777 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[hili
]);
779 XSetForeground(dpy
, xobj
->gc
, xobj
->TabColor
[shad
]);
780 XDrawSegments(dpy
, xobj
->win
, xobj
->gc
, segm
, 4);
783 int PtInRect(XPoint pt
, XRectangle rect
)
785 return ((pt
.x
>= rect
.x
) && (pt
.y
>= rect
.y
) &&
786 (pt
.x
<= rect
.x
+rect
.width
) && (pt
.y
<= rect
.y
+rect
.height
));
789 /* Arret pendant t*1/60 de secondes */
795 tv
= (struct timeval
*)calloc(1,sizeof(struct timeval
));
796 gettimeofday(tv
,NULL
);
799 while (((tv
->tv_usec
-tus
)+(tv
->tv_sec
-ts
)*1000000) < 16667*t
)
800 gettimeofday(tv
,NULL
);
804 int IsItDoubleClic(struct XObj
*xobj
)
809 return (FCheckTypedEvent(dpy
, ButtonPress
, &Event
));