Remove debugging output
[unicode-screensaver.git] / unicode.c
1 /* unicode (c) 2006 
2  * Joachim Breitner <mail@joachim-breitner.de>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  *
12  */
13
14 #include <X11/Xft/Xft.h>
15
16 #include "unicode-names.h"
17 #include "screenhack.h"
18
19 #define NUM_FONTS 2
20
21
22 struct unicode_state {
23         Bool blank;
24
25         XftFont*        fonts[NUM_FONTS];
26         XftFont*        tfont;
27         FcChar32        font_count[NUM_FONTS];
28         XftDraw*        draw;
29         XftColor        font_color;
30 };
31
32 static void *
33 unicode_init (Display *dpy, Window window)
34 {
35         struct unicode_state *state = malloc(sizeof(struct unicode_state));
36         state->blank = True;
37
38         Colormap cmap;
39         XWindowAttributes xgwa;
40         XGetWindowAttributes (dpy, window, &xgwa);
41         int i;
42
43         cmap = xgwa.colormap;
44
45         state->fonts[0] = XftFontOpen(dpy, 0, 
46                 XFT_FAMILY,  XftTypeString, "DejaVu Sans",
47                 XFT_PIXEL_SIZE, XftTypeInteger, xgwa.height-100,
48                 NULL
49                 );
50         state->fonts[1] = XftFontOpen(dpy, 0, 
51                 XFT_FAMILY,  XftTypeString, "FreeSans",
52                 XFT_PIXEL_SIZE, XftTypeInteger, xgwa.height-100,
53                 NULL
54                 );
55         state->tfont = XftFontOpen(dpy, 0, 
56                 XFT_FAMILY,  XftTypeString, "FreeSans",
57                 XFT_PIXEL_SIZE, XftTypeInteger, 40,
58                 NULL
59                 );
60         for (i = 0; i < NUM_FONTS; i++) {
61                 state->font_count[i] = FcCharSetCount(state->fonts[i]->charset);
62                 // printf("Font count: %d\n",state->font_count[i]);
63         }
64
65         state->draw = XftDrawCreate(dpy, window, xgwa.visual, cmap); 
66         XftColorAllocName(dpy, xgwa.visual ,cmap,"black",&state->font_color);
67
68         return state;
69 }
70
71 /* does a binary search on unicode_names */
72 /* (From gucharmap code) */
73 static inline const char *
74 get_unicode_data_name (FcChar32 uc)
75 {
76         unsigned long min = 0;
77         unsigned long mid;
78         unsigned long max = (sizeof(unicode_names)/sizeof(unicode_names[0])) - 1;
79
80         if (uc < unicode_names[0].index || uc > unicode_names[max].index)
81                 return "Out of range";
82
83         while (max >= min)
84         {
85                 mid = (min + max) / 2;
86                 if (uc > unicode_names[mid].index)
87                         min = mid + 1;
88                 else if (uc < unicode_names[mid].index)
89                         max = mid - 1;
90                 else
91                         return unicode_name_get_name(&unicode_names[mid]);
92         }
93
94         return "somethings wrong";
95 }
96
97
98 static unsigned long
99 unicode_draw (Display *dpy, Window win, struct unicode_state *state) {
100         XGlyphInfo      extents;
101         FcChar32        ucs4;
102         FcChar32        map[FC_CHARSET_MAP_SIZE];
103         FcChar32        next;
104         FcChar32        pickn;
105         FcChar32        pickc;
106         FcChar32        pick;   
107         char            name[100];
108         int             font;
109
110         if (state->blank) {
111                 XWindowAttributes xgwa;
112                 XGetWindowAttributes (dpy, win, &xgwa);
113
114                 font = random() % NUM_FONTS;
115
116                 pickn = random() % state->font_count[font];     
117
118                 pickc = 0;
119                 for (ucs4 = FcCharSetFirstPage (state->fonts[font]->charset, map, &next);
120                      ucs4 != FC_CHARSET_DONE;
121                      ucs4 = FcCharSetNextPage (state->fonts[font]->charset, map, &next))
122                 {
123                     int     i, j;
124                     for (i = 0; i < FC_CHARSET_MAP_SIZE; i++)
125                         if (map[i])
126                             for (j = 0; j < 32; j++)
127                                 if (map[i] & (1 << j))
128                                     if (pickc++ == pickn) 
129                                         pick = ucs4 + i * 32 + j;
130                 }
131                 
132
133                 sprintf(name,"U+%04X: ",pick);
134                 strcat(name, get_unicode_data_name(pick));
135
136                 XftTextExtents32(dpy,state->fonts[font],&pick,1,&extents); 
137                 XftDrawString32(state->draw,&state->font_color,state->fonts[font],
138                         xgwa.width/2  - extents.width/2  + extents.x,
139                         xgwa.height/2 - extents.height/2 + extents.y,
140                         &pick,1); 
141
142                 XftDrawStringUtf8(state->draw,&state->font_color,state->tfont,
143                         5,
144                         xgwa.height - 5,
145                         name,strlen(name)); 
146                 XSync (dpy, False);
147
148                 state->blank = False;
149                 return (7*1000*1000);
150         } else {
151                 XClearWindow (dpy, win);
152                 XSync (dpy, False);
153                 state->blank = True;
154                 return (1000*1000);
155         }
156
157 }
158
159 static void
160 unicode_reshape (Display *dpy, Window window, void *state,
161                  unsigned int width, unsigned int height) {
162 }               
163
164 static Bool
165 unicode_event (Display *dpy, Window window, void *state,
166                  XEvent *event) {
167                  return False;
168 }               
169
170 static void
171 unicode_free (Display *dpy, Window window, void *state) {
172 }               
173
174
175
176 char *progclass = "Unicode";
177
178 static char *unicode_defaults [] = {
179   ".background: white",
180   "*delay:      7",
181   0
182 };
183
184 static XrmOptionDescRec unicode_options [] = {
185   { "-delay",           ".delay",               XrmoptionSepArg, 0 },
186   { 0, 0, 0, 0 }
187 };
188
189 XSCREENSAVER_MODULE("Unicode",unicode)