Add DBus based freedesktop.org Notify support (uh, still a little hacky),
[metawatch.git] / mw_utility.c
1 /*
2  * (c) 2011 Siegen, Germany by Nils Faerber <nils.faerber@kernelconcepts.de>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23
24 #include "mw_utility.h"
25 #include "metawatch.h"
26
27 #include "fonts.h"
28
29 /*
30  * The pixmap buffer has at least one byte per pixel, even for monochrome (bpp=1)
31  * bitmaps
32  */
33 mw_buffer *mw_alloc_pbuffer(unsigned int res_x, unsigned int res_y, unsigned int bpp)
34 {
35         mw_buffer *nmwbuf;
36         int pbuf_size;
37
38         nmwbuf = (mw_buffer *) malloc(sizeof(mw_buffer));
39         if (!nmwbuf)
40                 return NULL;
41
42         nmwbuf->res_x = res_x;
43         nmwbuf->res_y = res_y;
44         nmwbuf->bpp = bpp;
45
46         pbuf_size = nmwbuf->res_x * nmwbuf->res_y * ((nmwbuf->bpp / 8) + 1);
47         nmwbuf->pbuf = malloc(pbuf_size);
48         if (!nmwbuf->pbuf) {
49                 free(nmwbuf);
50                 return NULL;
51         } else {
52                 memset(nmwbuf->pbuf, 0, pbuf_size);
53                 return nmwbuf;
54         }
55 }
56
57 void mw_free_pbuffer(mw_buffer *mwbuf)
58 {
59         if (!mwbuf)
60                 return;
61
62         free(mwbuf->pbuf);
63         free(mwbuf);
64 }
65
66 /*
67  * makes a buffer for sending to the watch from the drawing buffer, e.g.
68  * mw_send_bitmap(mw_fd, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len);
69  */
70 unsigned char *mw_make_mw_buffer(mw_buffer *mwbuf, int *buflen)
71 {
72         static unsigned char wbuf[96*12];
73         int x, y;
74         unsigned char clr;
75
76         memset(wbuf, 0, 96*12);
77
78         for (y = 0; y < mwbuf->res_y; y++) {
79                 for (x = 0; x < mwbuf->res_x; x++) {
80                         clr = *(unsigned char *)(mwbuf->pbuf+((y*mwbuf->res_x)+x));
81                         if (clr) {
82                                 *(unsigned char *)(wbuf+((y*12)+(x/8))) |= 1 << (x%8);
83                         };
84                 };
85         };
86         *buflen = mwbuf->res_y * 12;
87
88         return wbuf;
89 }
90
91 void mw_dump_mw_buffer(mw_buffer *mwbuf)
92 {
93         int x, y;
94         unsigned char clr;
95
96         for (y = 0; y < mwbuf->res_y; y++) {
97                 for (x = 0; x < mwbuf->res_x; x++) {
98                         clr = *(unsigned char *)(mwbuf->pbuf+((y*mwbuf->res_x)+x));
99                         if (clr)
100                                 fprintf(stderr, ".");
101                         else
102                                 fprintf(stderr, " ");
103                 };
104                 fprintf(stderr, "\n");
105         };
106 }
107
108
109 /* clear/fill entire buffer with color */
110 void mw_buf_clear(mw_buffer *mwbuf, mw_color clr)
111 {
112         int pbuf_size;
113
114         if (!mwbuf)
115                 return;
116         if (clr == MW_TRANSPARENT)
117                 return;
118
119         pbuf_size = mwbuf->res_x * mwbuf->res_y * ((mwbuf->bpp / 8) + 1);
120         memset(mwbuf->pbuf, clr, pbuf_size);
121 }
122
123 /* draw a single pixel */
124 void mw_buf_draw_pixel(mw_buffer *mwbuf, unsigned int x, unsigned int y, mw_color clr)
125 {
126         if (!mwbuf)
127                 return;
128         if (clr == MW_TRANSPARENT)
129                 return;
130
131         *(unsigned char *)(mwbuf->pbuf+((y*mwbuf->res_x)+x)) = clr;
132 }
133
134 void mw_buf_print(mw_buffer *mwbuf, unsigned int x, unsigned int y, char *text, unsigned char fsize, mw_color fgclr, mw_color bgclr)
135 {
136         unsigned int  i,j,z;
137         const unsigned char *data, *font_style;
138         unsigned char mask,xme,yme,offset;
139
140         if (text==NULL || strlen(text) == 0)
141                 return;
142
143         switch (fsize) {
144                 case 0:
145                         data = (const unsigned char *)FONT6x8;
146                         font_style = (const unsigned char *)FONT6x8;
147                         break;
148                 case 1:
149                         data = (const unsigned char *)FONT8x8F;
150                         font_style = (const unsigned char *)FONT8x8F;
151                         break;
152                 case 2:
153                         data = (const unsigned char *)FONT8x16;
154                         font_style = (const unsigned char *)FONT8x16;
155                         break;
156                 default:
157                         data = (const unsigned char *)FONT6x8;
158                         font_style = (const unsigned char *)FONT6x8;
159                         break;
160         };
161         xme = *data++;
162         yme = *data++;
163         offset = *data;
164
165         do {
166                 mask = 0x00;
167                 data =  (font_style + offset) + (offset * (int)(*text - 32));
168                 for (i=0; i < yme; i++) {
169                         mask |=0x80;
170                         for (j=x; j < (x + xme); j++) {
171                                 z = y + i;
172                                 if ((z < mwbuf->res_y) && (j < mwbuf->res_x)) {
173                                         if (*data & mask) {
174                                                 mw_buf_draw_pixel(mwbuf, j, z, fgclr);
175                                         } else {
176                                                 mw_buf_draw_pixel(mwbuf, j, z, bgclr);
177                                         }
178                                 }
179                                 mask >>= 1;
180                         }
181                         data++;
182                 }
183                 x += xme;
184                 text++;
185         } while (*text != '\0');
186 }
187
188 void mw_buf_draw_line_bresenham(mw_buffer *mwbuf, unsigned int xstart, unsigned int ystart, unsigned int xend, unsigned int yend, mw_color clr)
189 {
190         int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
191  
192         dx = xend - xstart;
193         dy = yend - ystart;
194  
195         incx = (dx >= 0) ? 1 : -1;
196         incy = (dy >= 0) ? 1 : -1;
197
198         if (dx<0)
199                 dx = -dx;
200         if (dy<0)
201                 dy = -dy;
202  
203         if (dx>dy) {
204                 pdx = incx; pdy = 0;
205                 ddx=incx; ddy=incy;
206                 es =dy;   el =dx;
207         } else {
208                 pdx=0;    pdy=incy;
209                 ddx=incx; ddy=incy;
210                 es =dx;   el =dy;
211         }
212  
213         x = xstart;
214         y = ystart;
215         err = el/2;
216         mw_buf_draw_pixel(mwbuf, x, y, clr);
217  
218         for (t = 0; t < el; ++t) {
219                 err -= es; 
220                 if (err < 0) {
221                         err += el;
222                         x += ddx;
223                         y += ddy;
224                 } else {
225                         x += pdx;
226                         y += pdy;
227                 }
228                 mw_buf_draw_pixel(mwbuf, x, y, clr);
229         }
230 }
231