]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/bmtable.c
(Lars) Remove symbolic links on "make distclean".
[lyx.git] / src / frontends / xforms / bmtable.c
1 /**
2  * \file bmtable.c
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12
13 #include "bmtable.h"
14 #include "lyx_xpm.h"
15 #ifdef HAVE_STDLIB_H
16 # include <stdlib.h>
17 #endif
18
19 #if defined(__cplusplus)
20 extern "C"
21 {
22 #endif
23
24 typedef struct   {
25         int nx, ny;     /**< Dimensions of the table */
26         int dx, dy;     /**< Size of each item */
27         int bx, by;      /**< Bitmap's position */
28         int bw, bh;      /**< Bitmap dimensions */
29         unsigned char const * bdata;     /**< Bitmap data */
30         int maxi;        /**< Number of items */
31         int i;   /**< Current position */
32         int mousebut; /**< mouse button pushed */
33         Pixmap pix;      /**< Pixmap from data (temporal) */
34 } BMTABLE_SPEC;
35
36
37 int handle_bitmaptable(FL_OBJECT * ob, int event, FL_Coord mx,
38                        FL_Coord my, int key, void * xev);
39
40
41 FL_OBJECT * fl_create_bmtable(int type, FL_Coord x, FL_Coord y,
42                               FL_Coord w, FL_Coord h, char const * label)
43 {
44         FL_OBJECT * ob;
45
46         ob = fl_make_object(FL_BMTABLE, type, x, y, w, h, label, handle_bitmaptable);
47         ob->boxtype = FL_BMTABLE_BOXTYPE;
48         ob->spec = fl_calloc(1, sizeof(BMTABLE_SPEC));
49         ((BMTABLE_SPEC *)ob->spec)->pix = 0;
50         ((BMTABLE_SPEC *)ob->spec)->bdata = 0;
51         ((BMTABLE_SPEC *)ob->spec)->mousebut = -1;
52         return ob;
53 }
54
55
56 FL_OBJECT *fl_add_bmtable(int type, FL_Coord x, FL_Coord y,
57                           FL_Coord w, FL_Coord h, char const *label)
58 {
59         FL_OBJECT *ob;
60
61         ob = fl_create_bmtable(type, x, y, w, h, label);
62         fl_add_object(fl_current_form, ob);
63
64         return ob;
65 }
66
67
68 static void draw_bitmaptable(FL_OBJECT *ob)
69 {
70         int i, j, lx;
71         FL_Coord mx, my;
72         FL_Coord xx, yy, ww, hh;
73         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
74         GC gc = fl_state[fl_get_vclass()].gc[0];
75         if (!sp) return;
76
77         /* draw the bounding box first */
78         lx = sp->maxi % sp->nx;
79         fl_drw_box(ob->boxtype, ob->x, ob->y, ob->w, ob->h, ob->col1, ob->bw);
80         if (lx) {
81                 i = FL_abs(ob->bw);
82                 xx = ob->x + sp->dx * lx + i;
83                 yy = ob->y + (sp->ny - 1) * sp->dy + i;
84                 ww = ob->x + ob->w - xx - i;
85                 hh = ob->y + ob->h - yy - i;
86                 fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
87                 fl_rectf(xx, yy, ww + i, hh + i, ob->col1);
88         }
89
90         /* draw the background bitmap */
91         if (sp->bdata)  {
92                 if (!sp->pix) {
93                         sp->pix = XCreatePixmapFromBitmapData(fl_get_display(), fl_winget(),
94                                                               (char*)sp->bdata,
95                                                               sp->bw, sp->bh,
96                                                               fl_get_flcolor(ob->lcol), fl_get_flcolor(ob->col1),
97                                                               /*DefaultDepth(fl_get_display(), DefaultScreen(fl_get_display()))*/ fl_state[fl_get_vclass()].depth);
98                         XFlush(fl_get_display());
99                 }
100         }
101         if (sp->pix) {
102                 /* Adjust position */
103                 if (sp->bx < FL_abs(ob->bw) + 1) {
104                         xx = FL_abs(ob->bw) - sp->bx + 1;
105                         mx = ob->x + FL_abs(ob->bw) + 1;
106                 } else  {
107                         xx = 0;
108                         mx = ob->x + sp->bx;
109                 }
110                 if (sp->by < FL_abs(ob->bw) + 1)  {
111                         yy = FL_abs(ob->bw) - sp->by + 1;
112                         my = ob->y + FL_abs(ob->bw) + 1;
113                 } else   {
114                         yy = 0;
115                         my = ob->y + sp->by;
116                 }
117                 ww = (mx + sp->bw < ob->x + ob->w - FL_abs(ob->bw)) ?
118                         sp->bw: ob->x + ob->w - FL_abs(ob->bw) - mx;
119                 hh = (my + sp->bh < ob->y + ob->h - FL_abs(ob->bw)) ?
120                         sp->bh: ob->y + ob->h - FL_abs(ob->bw) - my;
121
122                 i = FL_abs(ob->bw);
123                 j = hh - ((lx) ? sp->dy+2*i: 0);
124                 XCopyArea(fl_get_display(), sp->pix, fl_winget(), gc, xx, yy, ww, j, mx, my);
125                 XFlush(fl_get_display());
126                 if (lx) {
127                         XCopyArea(fl_get_display(), sp->pix, fl_winget(), gc, xx,
128                                   yy+j, lx*sp->dx-2*i, hh-j, mx, my+j);
129                         XFlush(fl_get_display());
130                 }
131         }
132
133
134         /* draw the grid if type > FLAT */
135         if (ob->type > FL_BMTABLE_FLAT)  {
136                 mx = ob->x + ob->w;
137                 my = ob->y + ob->h;
138                 ww = ob->w;
139                 for (yy= ob->y; yy<= my; yy+= sp->dy) {
140                         if (ob->boxtype!= FL_FLAT_BOX && (yy == ob->y || yy>my-sp->dy))
141                                 continue;
142                         if (lx>0 && yy>= my-sp->dy - sp->dy/2)
143                                 ww = lx*sp->dx;
144                         fl_diagline(ob->x, yy, ww, 1, FL_BOTTOM_BCOL);
145                         fl_diagline(ob->x, yy+1, ww-2, 1, FL_TOP_BCOL);
146                 }
147                 hh = ob->h;
148                 for (xx= ob->x; xx<= mx; xx+= sp->dx)  {
149                         if (ob->boxtype!= FL_FLAT_BOX && (xx == ob->x || xx>mx-sp->dx))
150                                 continue;
151                         if (lx>0 && xx>= ob->x + lx * sp->dx)
152                                 hh = (sp->ny - 1) * sp->dy;
153                         fl_diagline(xx, ob->y, 1, hh, FL_RIGHT_BCOL);
154                         fl_diagline(xx+1, ob->y + 1, 1, hh - 2, FL_LEFT_BCOL);
155                 }
156         }
157
158         /* Simulate a pushed button */
159         if (ob->pushed && 0 <= sp->i && sp->i < sp->maxi)  {
160                 i = sp->i % sp->nx;
161                 j = sp->i/sp->nx;
162                 ww = sp->dx-2*FL_abs(ob->bw);
163                 hh = sp->dy-2*FL_abs(ob->bw);
164                 xx = ob->x + sp->dx*i + FL_abs(ob->bw);
165                 yy = ob->y + sp->dy*j + FL_abs(ob->bw);
166                 fl_drw_frame(FL_DOWN_FRAME, xx, yy, ww, hh, ob->col1, ob->bw);
167         }
168 }
169
170
171 int handle_bitmaptable(FL_OBJECT * ob, int event, FL_Coord mx,
172                        FL_Coord my, int key, void * xev)
173 {
174         /* Silence warning about unused parameter */
175         (void) xev;
176
177         int i, j;
178         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
179
180         switch (event)  {
181         case FL_DRAW:
182                 draw_bitmaptable(ob);
183                 break;
184         case FL_MOUSE:
185                 if (!ob->belowmouse) {    /* This never happens. Why? */
186                         sp->i = -1;
187                         fl_redraw_object(ob);
188                         break;
189                 }
190                 i = (mx - ob->x)/sp->dx;  j = (my - ob->y)/sp->dy;
191                 if (i>= 0 && i< sp->nx && j>= 0 && j< sp->ny)   {
192                         i += j*sp->nx;
193                         if (i >= sp->maxi) i = -1;
194                         if (sp->i !=  i)  {
195                                 sp->i = i;
196                                 fl_redraw_object(ob);
197                         }
198                 }
199                 break;
200         case FL_PUSH:
201                 sp->mousebut = key;
202                 i = (mx - ob->x)/sp->dx + ((my - ob->y)/sp->dy)*sp->nx;
203                 if (0 <= i && i < sp->maxi)  {
204                         sp->i =  i;
205                         fl_redraw_object(ob);
206                 } else
207                         sp->i =  -1;
208                 break;
209         case FL_RELEASE:
210                 fl_redraw_object(ob);
211                 return 1;
212         case FL_FREEMEM:
213                 if (sp->pix) {
214                         XFreePixmap(fl_get_display(), sp->pix);
215                         XFlush(fl_get_display());
216                 }
217                 fl_free(((BMTABLE_SPEC*)ob->spec));
218                 break;
219         }
220         return 0;
221 }
222
223
224 /*
225  * The table has nx columns of dx width each and ny rows of dy height each.
226  * Initially the position of the firts item is supposed to be the same that
227  * the object position (x, y), and the number of items is supposed to be
228  * exactly nx*ny.
229  *
230  * The user could change these later. See below.
231  */
232 void fl_set_bmtable_data(FL_OBJECT * ob, int nx, int ny, int bw, int bh,
233                          unsigned char const * bdata)
234 {
235         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
236         if (sp) {
237                 sp->nx = nx;
238                 sp->ny = ny;
239                 sp->bx = FL_abs(ob->bw);
240                 sp->by = FL_abs(ob->bw);
241                 sp->dx = ob->w/nx;
242                 sp->dy = ob->h/ny;
243                 sp->i = -1;
244                 sp->maxi = sp->nx * sp->ny;
245                 sp->bw = bw;
246                 sp->bh = bh;
247                 sp->bdata = bdata;
248         }
249 }
250
251
252 void fl_set_bmtable_pixmap_data(FL_OBJECT * ob, int nx, int ny,
253                                 char ** pdata)
254 {
255         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
256         if (sp) {
257                 Pixmap dummy_shapemask = 0;
258                 XpmAttributes dumb_attributes;
259                 sp->nx = nx;
260                 sp->ny = ny;
261                 sp->bx = FL_abs(ob->bw);
262                 sp->by = FL_abs(ob->bw);
263                 sp->dx = ob->w/nx;
264                 sp->dy = ob->h/ny;
265                 sp->i = -1;
266                 sp->maxi = sp->nx * sp->ny;
267                 sp->bdata = 0;
268                 dumb_attributes.colormap = fl_state[fl_get_vclass()].colormap;
269                 dumb_attributes.closeness = 30000;
270                 dumb_attributes.valuemask = XpmColormap | XpmCloseness;
271                 if (XCreatePixmapFromData(fl_get_display(), fl_winget(), pdata,
272                                           &(sp->pix), &dummy_shapemask,
273                                           &dumb_attributes) == XpmSuccess) {
274                         sp->bw = dumb_attributes.width;
275                         sp->bh = dumb_attributes.height;
276                         XpmFreeAttributes(&dumb_attributes);
277                         if (dummy_shapemask) {
278                                 XFreePixmap(fl_get_display(), dummy_shapemask);
279                         }
280                 }
281         }
282 }
283
284
285 /*
286  *  This function works only for X11R6 or later
287  */
288 #if XlibSpecificationRelease > 5
289
290 void fl_set_bmtable_file(FL_OBJECT * ob, int nx, int ny, char const * filename)
291 {
292         int xh;
293         int yh;
294         unsigned int bw;
295         unsigned int bh;
296         unsigned char * bdata;
297
298         if (XReadBitmapFileData(filename, &bw, &bh,
299                                 &bdata, &xh, &yh) == BitmapSuccess)
300                 fl_set_bmtable_data(ob, nx, ny, bw, bh, bdata);
301         XFlush(fl_get_display());
302 }
303
304 #else
305
306 void fl_set_bmtable_file(FL_OBJECT * ob, int nx, int ny, char const * filename)
307 {
308         fprintf(stderr, "Set bmtable file: Sorry, I need X11 release 6 to do "
309                 "work!\n");
310 }
311
312 #endif
313
314
315
316 void fl_set_bmtable_pixmap_file(FL_OBJECT *ob, int nx, int ny, char const *filename)
317 {
318         /* extern Colormap color_map; */
319         BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
320         if (sp) {
321                 Pixmap dummy_shapemask = 0;
322                 XpmAttributes dumb_attributes;
323                 XpmColorSymbol xpm_col;
324                 sp->nx = nx;
325                 sp->ny = ny;
326                 sp->bx = FL_abs(ob->bw);
327                 sp->by = FL_abs(ob->bw);
328                 sp->dx = ob->w/nx;
329                 sp->dy = ob->h/ny;
330                 sp->i = -1;
331                 sp->maxi = sp->nx * sp->ny;
332                 sp->bdata = 0;
333
334                 xpm_col.name = NULL;
335                 xpm_col.value = "None";
336                 xpm_col.pixel = fl_get_flcolor(ob->col1);
337                 dumb_attributes.colormap = fl_state[fl_get_vclass()].colormap;
338                 dumb_attributes.numsymbols = 1;
339                 dumb_attributes.colorsymbols = &xpm_col;
340                 dumb_attributes.closeness = 30000;
341                 dumb_attributes.valuemask = XpmColormap | XpmCloseness | XpmColorSymbols;
342
343                 if (XReadPixmapFile(fl_get_display(), fl_winget(), (char *)filename,
344                                     &(sp->pix), &dummy_shapemask,
345                                     &dumb_attributes) == XpmSuccess) {
346                         sp->bw = dumb_attributes.width;
347                         sp->bh = dumb_attributes.height;
348                         XpmFreeAttributes(&dumb_attributes);
349                         if (dummy_shapemask) {
350                                 XFreePixmap(fl_get_display(), dummy_shapemask);
351                         }
352                 }
353                 /* XFlush(fl_get_display()); */
354         }
355 }
356
357
358 /*
359  * This function allows to adjust the position of the first item and its
360  * size (dx, dy). The input values are incremental, not absolute.
361  */
362 void fl_set_bmtable_adjust(FL_OBJECT *ob, int px, int py, int dx, int dy)
363 {
364         BMTABLE_SPEC *sp = (BMTABLE_SPEC *)ob->spec;
365         if (sp) {
366                 sp->bx += px;
367                 sp->by += py;
368                 sp->dx += dx;
369                 sp->dy += dy;
370         }
371 }
372
373 /*
374  * This function returns the table's selected position.
375  */
376 int fl_get_bmtable(FL_OBJECT *ob)
377 {
378         if ((BMTABLE_SPEC *)ob->spec)
379                 return  ((BMTABLE_SPEC *)ob->spec)->i;
380         else
381                 return 0;
382 }
383
384
385 /*
386  * You can change the max number of items if you want.
387  */
388 void fl_set_bmtable_maxitems(FL_OBJECT * ob, int i)
389 {
390         if (i > 0 && (BMTABLE_SPEC *)ob->spec)
391                 ((BMTABLE_SPEC *)ob->spec)->maxi = i;
392 }
393
394
395 int fl_get_bmtable_maxitems(FL_OBJECT * ob)
396 {
397         if ((BMTABLE_SPEC *)ob->spec)
398                 return  ((BMTABLE_SPEC *)ob->spec)->maxi;
399         else
400                 return 0;
401 }
402
403
404 void fl_replace_bmtable_item(FL_OBJECT * ob, int id, int cw, int ch, char * data)
405 {
406         /* Silence warnings about unused parameters */
407         (void) ob;
408         (void) id;
409         (void) cw;
410         (void) ch;
411         (void) data;
412
413         fprintf(stderr, "Replace bmtable item: Sorry, not yet implemented!\n");
414 }
415
416
417 void fl_get_bmtable_item(FL_OBJECT * ob, int id, int * cw, int * ch, char * data)
418 {
419         /* Silence warnings about unused parameters */
420         (void) ob;
421         (void) id;
422         (void) cw;
423         (void) ch;
424         (void) data;
425
426         fprintf(stderr, "Get bmtable item: Sorry, not yet implemented!\n");
427 }
428
429 void fl_set_bmtable(FL_OBJECT * ob, int pushed, int pos)
430 {
431         if ((BMTABLE_SPEC *)ob->spec)
432                 ((BMTABLE_SPEC *)ob->spec)->i = (pushed) ? pos: -1;
433 }
434
435
436 int fl_get_bmtable_numb(FL_OBJECT *ob)
437 {
438         if ((BMTABLE_SPEC *)ob->spec)
439                 return ((BMTABLE_SPEC *)ob->spec)->mousebut;
440         else
441                 return 0;
442 }
443
444
445 Pixmap fl_get_bmtable_pixmap(FL_OBJECT * ob)
446 {
447         if ((BMTABLE_SPEC *)ob->spec)
448                 return ((BMTABLE_SPEC *)ob->spec)->pix;
449         else
450                 return 0;
451 }
452
453
454 void fl_draw_bmtable_item(FL_OBJECT * ob, int i, Drawable d, int xx, int yy)
455 {
456         int x;
457         int y;
458         int w;
459         int h;
460         GC gc = fl_state[fl_get_vclass()].gc[0];
461         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
462
463         if (sp && sp->pix) {
464                 x = (i % sp->nx)*sp->dx + FL_abs(ob->bw);
465                 y = (i/sp->nx)*sp->dy + FL_abs(ob->bw);
466                 w = sp->dx-2*FL_abs(ob->bw);
467                 h = sp->dy-2*FL_abs(ob->bw);
468                 XCopyArea(fl_get_display(), sp->pix, d, gc, x, y, w, h, xx, yy);
469                 XFlush(fl_get_display());
470         }
471 }
472
473 /* Free the current bitmap and pixmap in preparation for installing a new one */
474 void fl_free_bmtable_bitmap(FL_OBJECT * ob)
475 {
476         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
477
478         /* dump the temporary pixmap */
479         if (sp && sp->pix) {
480                 XFreePixmap(fl_get_display(), sp->pix);
481                 XFlush(fl_get_display());
482                 sp->pix = 0;
483         }
484
485         /* and free the space taken by bdata etc. */
486         if (sp && sp->bdata) {
487                 fl_free((void*)sp->bdata);
488                 sp->bdata = 0;
489         }
490 }
491
492 /* Free the current pixmap in preparation for installing a new one */
493 /* This is needed when using data instead of files to set bitmaps */
494 void fl_free_bmtable_pixmap(FL_OBJECT *ob)
495 {
496         BMTABLE_SPEC * sp = (BMTABLE_SPEC *)ob->spec;
497
498         /* dump the temporary pixmap */
499         if (sp && sp->pix) {
500                 XFreePixmap(fl_get_display(), sp->pix);
501                 XFlush(fl_get_display());
502                 sp->pix = 0;
503         }
504 }
505
506 #if defined(__cplusplus)
507 }
508 #endif