Import upstream version 0.99.2
[fmit.git] / src / modules / GLGraph.cpp
1 // Copyright 2004 "Gilles Degottex"
2
3 // This file is part of "Music"
4
5 // "Music" is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or
8 // (at your option) any later version.
9 //
10 // "Music" is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
20 #include "GLGraph.h"
21
22 static const unsigned char g_icon_graph[] = {
23     0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
24     0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
25     0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, 0xf4, 0x00, 0x00, 0x07,
26     0xa8, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xad, 0x97, 0x6b, 0x6c, 0x14,
27     0xd7, 0x15, 0xc7, 0x7f, 0x33, 0x3b, 0x3b, 0x6b, 0xef, 0xfa, 0xbd, 0xeb,
28     0xe7, 0x62, 0x13, 0xec, 0xb5, 0x8d, 0x63, 0xb0, 0x0d, 0xc8, 0x50, 0x88,
29     0x81, 0xa4, 0x22, 0x98, 0x12, 0x20, 0x69, 0xd2, 0x22, 0x85, 0xa6, 0x4a,
30     0xda, 0xa8, 0x1f, 0xac, 0x44, 0x0a, 0x1f, 0x88, 0x54, 0x91, 0x22, 0x5a,
31     0xb5, 0x11, 0x52, 0x95, 0x3e, 0x48, 0x9b, 0x5a, 0xad, 0x1a, 0xa5, 0x2d,
32     0xb4, 0x5f, 0xa2, 0x96, 0x52, 0x68, 0x8b, 0x6d, 0x5e, 0x06, 0x1b, 0x53,
33     0xbc, 0x7e, 0x61, 0x83, 0xb1, 0xc1, 0x76, 0xfc, 0xc0, 0xe0, 0xc7, 0xda,
34     0xde, 0x5d, 0x7b, 0xbd, 0xbb, 0xde, 0x99, 0xdb, 0x0f, 0x6b, 0x90, 0x31,
35     0x36, 0x21, 0x88, 0x23, 0x8d, 0xae, 0x34, 0x9a, 0x7b, 0xfe, 0xbf, 0x7b,
36     0xce, 0x3d, 0xf7, 0x9e, 0x91, 0x78, 0x0c, 0xb3, 0x95, 0x94, 0xa5, 0x03,
37     0xdf, 0x04, 0x26, 0x81, 0x11, 0xa0, 0x6e, 0xb4, 0xa6, 0x7c, 0xf4, 0x71,
38     0xe6, 0x7e, 0x99, 0x49, 0x8f, 0x21, 0xfe, 0x36, 0x50, 0x0e, 0x18, 0xe7,
39     0xbc, 0x16, 0x40, 0x33, 0x70, 0x7a, 0xf6, 0xb9, 0x38, 0x5a, 0x53, 0x3e,
40     0xfd, 0xd4, 0x01, 0x6c, 0x25, 0x65, 0xd1, 0x40, 0x37, 0x60, 0x7b, 0xef,
41     0x8d, 0x52, 0x36, 0xae, 0xc9, 0x65, 0xca, 0xe7, 0xa7, 0xf5, 0xe6, 0x00,
42     0x57, 0x3b, 0xfb, 0x68, 0x6a, 0xef, 0x65, 0x64, 0xdc, 0x0b, 0x10, 0x00,
43     0x2e, 0xcd, 0x01, 0xaa, 0x1f, 0xad, 0x29, 0x17, 0x4f, 0x03, 0xe0, 0x20,
44     0xf0, 0xe3, 0x6f, 0x6c, 0x2c, 0xe4, 0xf0, 0x07, 0x6f, 0xd3, 0x75, 0x37,
45     0x80, 0xa6, 0x0b, 0x22, 0x8c, 0x12, 0xb6, 0x18, 0x23, 0xd6, 0x28, 0x03,
46     0x4d, 0xed, 0x3d, 0x1c, 0x3f, 0xdb, 0xc0, 0xc9, 0xea, 0x26, 0x86, 0x5c,
47     0x9e, 0x7b, 0x53, 0xef, 0x00, 0xff, 0x04, 0x8e, 0x01, 0xe7, 0x47, 0x6b,
48     0xca, 0x67, 0xbe, 0x32, 0x80, 0xad, 0xa4, 0x2c, 0x01, 0xf8, 0x42, 0x35,
49     0x2a, 0xd1, 0x15, 0x9f, 0x1e, 0x60, 0x64, 0xca, 0x84, 0xa6, 0x0b, 0x74,
50     0x5d, 0xa0, 0x0b, 0xd0, 0x05, 0x08, 0x01, 0x31, 0x91, 0x32, 0xd6, 0x68,
51     0x23, 0xd6, 0x68, 0x99, 0x5b, 0xdd, 0xbd, 0x9c, 0xa8, 0x6e, 0xe2, 0xc4,
52     0xf9, 0x26, 0x86, 0xc7, 0xee, 0xc3, 0x8c, 0x03, 0x27, 0x67, 0x61, 0x2a,
53     0x46, 0x6b, 0xca, 0x7d, 0x8f, 0x0b, 0xb0, 0x17, 0xf8, 0xd5, 0xde, 0xef,
54     0x96, 0xf2, 0xf2, 0xb6, 0x17, 0x99, 0xf0, 0x69, 0x08, 0x21, 0x10, 0x3a,
55     0xe8, 0x22, 0x0c, 0x31, 0x13, 0x0a, 0xd1, 0xd1, 0xd3, 0x48, 0x63, 0xdb,
56     0x19, 0x84, 0x26, 0x78, 0xe5, 0xc5, 0x77, 0x49, 0x4b, 0x8e, 0x27, 0x29,
57     0xc6, 0x40, 0xff, 0x40, 0x3f, 0xff, 0xae, 0x6e, 0xe4, 0x64, 0x75, 0xf3,
58     0x5c, 0x18, 0x1f, 0x70, 0x70, 0xb4, 0xa6, 0xfc, 0xa3, 0xc7, 0x01, 0x68,
59     0x31, 0xa9, 0x4a, 0x41, 0xe3, 0xe7, 0x87, 0xe8, 0x1f, 0x0f, 0x8b, 0x0a,
60     0x01, 0xb7, 0x87, 0x7b, 0xa8, 0x6f, 0x3d, 0xc7, 0x95, 0x96, 0x2a, 0x6e,
61     0x0e, 0x3a, 0x29, 0x7c, 0x21, 0x85, 0x8c, 0x3c, 0x1b, 0xc7, 0x7e, 0xd7,
62     0xcc, 0x81, 0xd7, 0x3f, 0x27, 0x2b, 0x6f, 0x15, 0xba, 0x1e, 0x4e, 0x7f,
63     0x7c, 0x94, 0x42, 0x6a, 0xbc, 0x42, 0x5f, 0x7f, 0x1f, 0xff, 0x38, 0xed,
64     0xe4, 0xc8, 0x89, 0x5a, 0x74, 0x5d, 0x17, 0x7a, 0x60, 0x32, 0x67, 0xdc,
65     0x79, 0xf4, 0x16, 0x80, 0xb2, 0x88, 0xf8, 0x2a, 0xa0, 0x60, 0xd7, 0x0b,
66     0xab, 0x99, 0x0a, 0x04, 0xb8, 0xdc, 0x72, 0x96, 0xba, 0xc6, 0x4a, 0x2e,
67     0xb7, 0x9d, 0x25, 0x7e, 0x99, 0x46, 0xd1, 0xc6, 0x65, 0xe4, 0xbd, 0x6e,
68     0x24, 0xdb, 0x9c, 0x4f, 0x47, 0xd7, 0x38, 0x75, 0x93, 0x5d, 0x88, 0xf4,
69     0x20, 0x2d, 0xd7, 0xab, 0x58, 0xbe, 0xa2, 0x08, 0x49, 0x91, 0xd1, 0x75,
70     0x81, 0x77, 0x5a, 0xc3, 0x33, 0xad, 0x11, 0x13, 0x95, 0xc6, 0x2f, 0xde,
71     0xdf, 0xc3, 0x90, 0xcb, 0x4d, 0x45, 0x6d, 0xab, 0x34, 0xd5, 0x53, 0xbb,
72     0x12, 0xe8, 0x01, 0xb4, 0x05, 0x01, 0x80, 0xef, 0x01, 0xbc, 0xb9, 0x6b,
73     0x23, 0xdb, 0xdf, 0x59, 0xcf, 0x92, 0x62, 0x23, 0x39, 0x9b, 0x53, 0x79,
74     0xe9, 0x15, 0x07, 0xb7, 0x3d, 0x6e, 0x1a, 0xda, 0x5d, 0x84, 0x9a, 0x55,
75     0x42, 0x9e, 0x19, 0x3c, 0x2e, 0x17, 0x5f, 0x7b, 0x35, 0x15, 0x77, 0x9e,
76     0x87, 0xab, 0x97, 0x6b, 0xd9, 0xe5, 0xfe, 0x3e, 0x71, 0xb6, 0x24, 0x74,
77     0x21, 0x21, 0x66, 0x53, 0x65, 0x36, 0xc9, 0x00, 0x74, 0xf5, 0x0f, 0x23,
78     0x74, 0xcd, 0x1b, 0x1c, 0xeb, 0xd5, 0x00, 0x0b, 0xe0, 0x79, 0x08, 0xc0,
79     0x56, 0x52, 0xa6, 0x02, 0x7b, 0x72, 0x9f, 0x49, 0xa5, 0x30, 0x6f, 0x19,
80     0x2b, 0xb2, 0x56, 0xe3, 0xd8, 0xe0, 0xe3, 0xd4, 0xdd, 0x56, 0x66, 0xaa,
81     0xac, 0x04, 0xbd, 0xd3, 0xb8, 0x07, 0x87, 0x98, 0x1e, 0xf3, 0x12, 0x63,
82     0x8e, 0x23, 0x2e, 0xca, 0xc6, 0xc8, 0x35, 0x0f, 0x11, 0xf9, 0x46, 0x3a,
83     0x27, 0x9a, 0x19, 0x19, 0xea, 0x21, 0x29, 0x35, 0x05, 0x21, 0x08, 0x03,
84     0xe8, 0x90, 0x12, 0xa7, 0x72, 0x7b, 0x68, 0x8c, 0x5b, 0x7d, 0x43, 0xe8,
85     0x01, 0x6f, 0x03, 0x42, 0x17, 0x84, 0x4b, 0x77, 0xc1, 0x14, 0xec, 0x04,
86     0xac, 0x6f, 0xbe, 0x5c, 0xc2, 0x74, 0x50, 0xa7, 0x64, 0xf5, 0x16, 0xfe,
87     0x73, 0xf9, 0x30, 0xc9, 0xb9, 0x16, 0x2e, 0xd5, 0xb5, 0x62, 0xb7, 0x3e,
88     0xc3, 0xd6, 0x9c, 0x9d, 0x14, 0xe7, 0x6f, 0x62, 0x65, 0xee, 0x5a, 0x50,
89     0x65, 0x76, 0xff, 0xb0, 0x98, 0x95, 0x05, 0x4b, 0x18, 0x77, 0xf8, 0xb8,
90     0xdc, 0x7c, 0x8a, 0x82, 0x55, 0xeb, 0x90, 0x0d, 0x06, 0x84, 0x90, 0x00,
91     0x41, 0x42, 0x94, 0xc2, 0x9f, 0xcf, 0xb4, 0x01, 0x30, 0xe3, 0x1d, 0x6e,
92     0x00, 0xa6, 0x1e, 0x05, 0xf0, 0x56, 0x84, 0x6a, 0xe4, 0xdb, 0xa5, 0xeb,
93     0x98, 0x09, 0x09, 0x36, 0x15, 0x7f, 0x9d, 0x9f, 0xfd, 0xe5, 0x3d, 0x76,
94     0x3c, 0xbf, 0x1a, 0x29, 0x52, 0x62, 0x55, 0x66, 0x31, 0x3f, 0xdd, 0xf7,
95     0x5b, 0x64, 0xd9, 0x10, 0x5e, 0x25, 0xf0, 0xdc, 0xca, 0x52, 0xfa, 0xda,
96     0xeb, 0x31, 0x2f, 0x57, 0x69, 0xac, 0xae, 0xc5, 0x3b, 0x36, 0x4c, 0x62,
97     0x4a, 0x1a, 0x42, 0x40, 0x74, 0xa4, 0x82, 0x2c, 0x43, 0x45, 0xed, 0x55,
98     0x84, 0x10, 0xba, 0x7f, 0xf0, 0x6a, 0x23, 0x30, 0x74, 0x4f, 0x4c, 0x9e,
99     0x17, 0xfe, 0x58, 0x60, 0x6b, 0xe9, 0x73, 0x2b, 0x31, 0x47, 0x46, 0x22,
100     0xcb, 0x12, 0xe9, 0xc9, 0xe9, 0xc4, 0x9b, 0x92, 0x71, 0x0f, 0xfb, 0x30,
101     0xd9, 0x15, 0xba, 0xee, 0xde, 0x40, 0x0f, 0x05, 0x51, 0x0c, 0x12, 0x48,
102     0x1a, 0xdd, 0x03, 0xed, 0x64, 0xa6, 0x67, 0x33, 0xe4, 0x74, 0x63, 0x4a,
103     0x32, 0x72, 0x6b, 0xaa, 0x8d, 0xfe, 0xde, 0x0e, 0x8c, 0x06, 0x09, 0xa3,
104     0x41, 0x22, 0xce, 0x62, 0x60, 0x6a, 0x3a, 0x40, 0x4d, 0x53, 0x27, 0x22,
105     0xe4, 0xef, 0x08, 0x4d, 0x8e, 0x78, 0x81, 0xe1, 0x7b, 0x9a, 0xf3, 0x23,
106     0xb0, 0x13, 0x50, 0x5f, 0xda, 0x5c, 0x44, 0x48, 0x13, 0x28, 0x86, 0xf0,
107     0x61, 0xb3, 0x36, 0x7f, 0x3d, 0x5f, 0x74, 0x5f, 0x21, 0x22, 0xdd, 0x48,
108     0x4f, 0x4d, 0x17, 0x53, 0x9e, 0x71, 0x24, 0x49, 0xe3, 0x8d, 0x1f, 0xed,
109     0xa4, 0xb5, 0xbb, 0x91, 0x88, 0x25, 0x46, 0x88, 0x80, 0x19, 0xb7, 0x4e,
110     0x44, 0x8e, 0x81, 0x0b, 0x8d, 0xff, 0xa5, 0xa4, 0x64, 0x33, 0x26, 0x55,
111     0xc5, 0x62, 0x32, 0x70, 0xaa, 0xa6, 0x8d, 0x40, 0x30, 0x84, 0xe6, 0x1b,
112     0x73, 0x02, 0x21, 0xc0, 0xb5, 0x18, 0xc0, 0x6b, 0xaa, 0x51, 0x61, 0xcb,
113     0xfa, 0x15, 0x08, 0x21, 0xe8, 0xbf, 0xdb, 0xc3, 0x2f, 0x8f, 0x1c, 0xa2,
114     0xfe, 0x7a, 0x1d, 0x21, 0x97, 0x17, 0xd3, 0x1a, 0x85, 0x89, 0x19, 0x0f,
115     0x6d, 0x9d, 0x8d, 0xc4, 0x26, 0xc6, 0xd1, 0x3e, 0xdc, 0xcc, 0x89, 0xbf,
116     0x9e, 0xe4, 0xba, 0xf7, 0x2a, 0x9f, 0xdc, 0xf8, 0x08, 0x81, 0xc0, 0x9c,
117     0xa7, 0xd2, 0x54, 0x55, 0x83, 0xec, 0x77, 0x91, 0x9c, 0x94, 0x01, 0x40,
118     0x45, 0x6d, 0x2b, 0x00, 0x81, 0xd1, 0x6e, 0x27, 0x30, 0x0a, 0xe8, 0x0f,
119     0xa5, 0xc0, 0x56, 0x52, 0x16, 0x05, 0x6c, 0x7b, 0xbe, 0x38, 0x0f, 0x73,
120     0x84, 0x09, 0x59, 0x96, 0xf8, 0xc1, 0x4f, 0xbe, 0x43, 0xde, 0xba, 0x2c,
121     0xf6, 0xec, 0xdb, 0x8d, 0x65, 0x83, 0x19, 0xd5, 0x66, 0x40, 0x8e, 0x90,
122     0xb8, 0x7e, 0xab, 0x01, 0x2d, 0x34, 0x89, 0x21, 0x56, 0xa6, 0x72, 0xe8,
123     0x04, 0x7f, 0xef, 0xfd, 0x1b, 0x02, 0x81, 0xd0, 0x20, 0xe4, 0xd1, 0xb8,
124     0x31, 0xdc, 0x4e, 0xcb, 0xf5, 0x16, 0x20, 0x5c, 0x09, 0x55, 0x75, 0x6d,
125     0x08, 0x2d, 0xe4, 0xf2, 0xdf, 0x69, 0xeb, 0x99, 0x9b, 0xff, 0xf9, 0x11,
126     0xd8, 0x0e, 0x44, 0xec, 0xd8, 0x5c, 0x84, 0x10, 0x00, 0x1a, 0x7d, 0xee,
127     0x6e, 0x32, 0x97, 0x2f, 0xe3, 0xfc, 0x50, 0x15, 0x22, 0x26, 0x7c, 0x9f,
128     0x98, 0xec, 0x06, 0x5a, 0xbb, 0x9b, 0xd9, 0xff, 0xce, 0x01, 0x62, 0x7f,
129     0x1e, 0xcf, 0x1f, 0x0f, 0x7f, 0x8a, 0x92, 0xa8, 0x30, 0xe3, 0xd2, 0x08,
130     0xf6, 0x87, 0x88, 0x56, 0x62, 0xd8, 0x9a, 0x5f, 0xca, 0xf8, 0x98, 0x8b,
131     0x60, 0x30, 0xc8, 0xb5, 0xae, 0x41, 0x86, 0xc7, 0x3c, 0x68, 0x01, 0x8f,
132     0x73, 0x56, 0x67, 0x78, 0x31, 0x80, 0x6f, 0x19, 0x0c, 0x32, 0xdb, 0x4a,
133     0x0a, 0x00, 0x30, 0x1a, 0x14, 0xb2, 0x13, 0x72, 0x79, 0xff, 0x0f, 0x7b,
134     0x51, 0x57, 0x4a, 0xc8, 0xaa, 0x44, 0x60, 0x20, 0x44, 0xc8, 0x23, 0xe8,
135     0x98, 0xe8, 0x64, 0x7a, 0xca, 0x47, 0x65, 0x79, 0x35, 0x07, 0x3f, 0xde,
136     0x8f, 0x3f, 0xe8, 0x47, 0x8d, 0x57, 0x29, 0x5c, 0x53, 0xc4, 0xda, 0x67,
137     0xd7, 0x91, 0x9e, 0x9e, 0x41, 0x9a, 0xdd, 0x8e, 0xaa, 0xaa, 0x54, 0x5e,
138     0x9a, 0x2d, 0x3f, 0xf7, 0x1d, 0x27, 0xe0, 0x06, 0xfc, 0x0f, 0x01, 0xd8,
139     0x4a, 0xca, 0x22, 0x81, 0xed, 0x1b, 0x8a, 0xb2, 0x89, 0x8b, 0xb6, 0x20,
140     0x84, 0x00, 0x49, 0xe2, 0xd7, 0xfb, 0x7e, 0xc3, 0x9e, 0xfd, 0xbb, 0xe9,
141     0xbf, 0xd8, 0x8f, 0x84, 0x84, 0x2c, 0xc9, 0xe4, 0xda, 0x73, 0xd9, 0x90,
142     0x57, 0x82, 0x7b, 0x62, 0x82, 0xcc, 0xac, 0x2c, 0x3e, 0x3b, 0x74, 0x14,
143     0x8f, 0xdb, 0x8d, 0x24, 0x49, 0x98, 0x4c, 0x26, 0xcc, 0x16, 0xcb, 0x03,
144     0x9b, 0x6a, 0xb6, 0xfc, 0x42, 0xd3, 0xb7, 0x9b, 0x5b, 0xe6, 0xaf, 0x7e,
145     0x6e, 0x04, 0xb6, 0x01, 0x96, 0x1d, 0x9b, 0x8a, 0x40, 0x02, 0x59, 0x0a,
146     0xdf, 0x51, 0x45, 0xcf, 0xae, 0xe6, 0xf4, 0x27, 0xd5, 0x34, 0x5d, 0x75,
147     0x32, 0x39, 0xe9, 0xc5, 0x9e, 0x9c, 0x4e, 0x6c, 0x6c, 0x1c, 0x29, 0xa9,
148     0xa9, 0xd8, 0x12, 0x13, 0xc3, 0x0e, 0x14, 0x85, 0x04, 0xab, 0x75, 0xbe,
149     0x5f, 0x00, 0xee, 0x8c, 0x4c, 0xd0, 0x7a, 0x73, 0x00, 0x3d, 0xe8, 0x6b,
150     0xd3, 0xfd, 0x1e, 0xff, 0xfc, 0xfc, 0xcf, 0x05, 0x78, 0x0d, 0x60, 0xfb,
151     0xa6, 0xa2, 0x87, 0xae, 0xc7, 0x34, 0xbb, 0x9d, 0x34, 0xbb, 0x7d, 0x41,
152     0x81, 0x2f, 0xb3, 0xca, 0x4b, 0xe1, 0xdd, 0xaf, 0xf9, 0x5c, 0x4e, 0x20,
153     0x08, 0x4c, 0xcc, 0xff, 0x46, 0x9e, 0x3d, 0xfb, 0x77, 0x16, 0xaf, 0xc8,
154     0x24, 0xc5, 0x16, 0xfb, 0x44, 0x42, 0x8b, 0xd9, 0xfd, 0xf2, 0x1b, 0xee,
155     0x74, 0x12, 0x0e, 0xff, 0x43, 0x6d, 0x9a, 0x0c, 0x6c, 0x01, 0x62, 0x76,
156     0x6c, 0x2e, 0x7a, 0xaa, 0xe2, 0xd3, 0x81, 0x20, 0x17, 0x1b, 0x3a, 0x10,
157     0x5a, 0x70, 0x30, 0x30, 0x72, 0x73, 0x90, 0x05, 0xc2, 0x7f, 0x0f, 0xa0,
158     0x18, 0xa0, 0x30, 0x37, 0xe3, 0xa9, 0x02, 0x5c, 0x70, 0xde, 0xc0, 0x1f,
159     0x9c, 0x41, 0x9b, 0xf6, 0x34, 0x10, 0x5e, 0xf9, 0xc8, 0x62, 0x00, 0x21,
160     0x80, 0xcf, 0x8e, 0x5d, 0xa0, 0x77, 0xf0, 0xa9, 0xb4, 0xfa, 0x00, 0x73,
161     0xca, 0x6f, 0xa0, 0x1e, 0x18, 0x03, 0x16, 0x6c, 0x4c, 0x15, 0xe0, 0x4f,
162     0x42, 0xd7, 0xca, 0x8e, 0x9f, 0x6b, 0xb4, 0x1f, 0x3f, 0xd7, 0x48, 0x7e,
163     0x96, 0x9d, 0xc2, 0xdc, 0x0c, 0x0a, 0x72, 0x33, 0x28, 0xcc, 0xcd, 0x20,
164     0xdf, 0x61, 0x27, 0xd2, 0xa4, 0x7e, 0x25, 0x71, 0x21, 0x04, 0x15, 0xb5,
165     0xad, 0x08, 0xa1, 0xfb, 0x7d, 0x03, 0x4d, 0xd7, 0x58, 0x24, 0xfc, 0x30,
166     0xdb, 0x13, 0x9a, 0x97, 0xae, 0x5b, 0x63, 0x4a, 0x74, 0x7c, 0x2c, 0x1b,
167     0xcd, 0xb9, 0x92, 0x41, 0x79, 0xa0, 0xa6, 0x64, 0x59, 0x22, 0x67, 0x69,
168     0x0a, 0x05, 0x39, 0x19, 0xb3, 0x60, 0xe9, 0xac, 0x70, 0x2c, 0x21, 0xca,
169     0x1c, 0xb1, 0x28, 0xc0, 0xc5, 0x86, 0x0e, 0x5e, 0xdd, 0x7b, 0x18, 0xcd,
170     0xef, 0xfd, 0xdf, 0xb8, 0xf3, 0xe8, 0x87, 0xc0, 0x79, 0xc0, 0xbb, 0x28,
171     0xc0, 0xec, 0x58, 0x00, 0x64, 0x18, 0x63, 0xd3, 0xe2, 0x55, 0x5b, 0x96,
172     0x43, 0xb1, 0x58, 0x1d, 0xb2, 0x29, 0x3a, 0x5b, 0x36, 0x46, 0x38, 0x24,
173     0x59, 0x89, 0x7b, 0x60, 0x92, 0x24, 0x91, 0x95, 0x9e, 0x14, 0x06, 0xca,
174     0x49, 0xbf, 0x3f, 0x46, 0x5b, 0x22, 0x99, 0x09, 0x69, 0xbc, 0xf5, 0xc1,
175     0xef, 0xa9, 0xbc, 0xd4, 0x46, 0x60, 0xb4, 0xeb, 0x63, 0xef, 0x8d, 0xca,
176     0x7f, 0x01, 0x67, 0x1e, 0x19, 0x81, 0x39, 0x96, 0x0c, 0xc4, 0x03, 0x71,
177     0x40, 0x2c, 0xa0, 0x02, 0x18, 0xe3, 0x33, 0x6c, 0x26, 0xeb, 0x32, 0x87,
178     0xc1, 0x6c, 0xcd, 0x96, 0x4d, 0x51, 0x8e, 0x30, 0x94, 0x21, 0x7a, 0xbe,
179     0xb3, 0xcc, 0x25, 0x89, 0x04, 0x67, 0x34, 0x06, 0x86, 0xc6, 0xd0, 0x43,
180     0xc1, 0xdb, 0xe3, 0xf5, 0x47, 0xde, 0x15, 0x5a, 0xb0, 0x0b, 0x68, 0x7d,
181     0x5c, 0x80, 0xf9, 0x66, 0x9e, 0x05, 0x89, 0x9b, 0x03, 0x65, 0x04, 0x50,
182     0xad, 0x99, 0xc9, 0x6a, 0xc2, 0x52, 0x87, 0xc1, 0x9c, 0x90, 0x6d, 0x30,
183     0x59, 0x1c, 0x92, 0x12, 0xe9, 0x90, 0x64, 0xd9, 0x0c, 0x20, 0x74, 0x6d,
184     0x72, 0x7a, 0xa0, 0xf9, 0x43, 0x5f, 0xdf, 0x95, 0x6b, 0x40, 0x2d, 0xe1,
185     0x4d, 0xf8, 0x44, 0x00, 0x0b, 0x99, 0x65, 0x1e, 0x50, 0x2c, 0xa0, 0x80,
186     0x24, 0x99, 0x12, 0x1d, 0xa9, 0x06, 0x73, 0x82, 0x35, 0x30, 0x72, 0xab,
187     0x5b, 0xf3, 0xb9, 0xa6, 0x08, 0xff, 0xa2, 0x39, 0x1f, 0xe1, 0xeb, 0x89,
188     0x00, 0x16, 0xf2, 0x31, 0x1f, 0x2a, 0x92, 0x70, 0xe3, 0x71, 0x9d, 0xf0,
189     0x11, 0xbc, 0xa8, 0xfd, 0x1f, 0xbf, 0x8b, 0x3f, 0x6e, 0xf8, 0x00, 0xc8,
190     0x03, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60,
191     0x82
192 };
193
194 #include <iostream>
195 using namespace std;
196 #include <qtooltip.h>
197 #include <qimage.h>
198 #include <qboxlayout.h>
199 #include <qwidgetaction.h>
200 #include <GL/glut.h>
201 #include <Music/Music.h>
202 using namespace Music;
203
204 GLGraph::GLGraph(QWidget* parent)
205 : QGLWidget(parent)
206 , View(tr("Captured Sound"), this)
207 , m_skip(1)
208 , m_new_values(false)
209 {
210         // settings
211         QPixmap img;
212         img.loadFromData(g_icon_graph, sizeof(g_icon_graph), "PNG");
213         setting_show->setIcon(QIcon(img));
214         setting_show->setChecked(true);
215
216         setting_showWaveForm = new QAction(tr("Show Wave Form"), this);
217         setting_showWaveForm->setCheckable(true);
218         connect(setting_showWaveForm, SIGNAL(toggled(bool)), this, SLOT(update()));
219         setting_showWaveForm->setChecked(true);
220         m_popup_menu.addAction(setting_showWaveForm);
221
222         setting_autoScale = new QAction(tr("Auto scale"), this);
223         setting_autoScale->setCheckable(true);
224         connect(setting_autoScale, SIGNAL(toggled(bool)), this, SLOT(update()));
225         setting_autoScale->setChecked(false);
226         m_popup_menu.addAction(setting_autoScale);
227
228         QHBoxLayout* scaleFactorActionLayout = new QHBoxLayout(&m_popup_menu);
229
230         QLabel* scaleFactorActionTitle = new QLabel(tr("Scale factor"), &m_popup_menu);
231         scaleFactorActionLayout->addWidget(scaleFactorActionTitle);
232
233         setting_spinScaleFactor = new QSpinBox(&m_popup_menu);
234         setting_spinScaleFactor->setMinimum(1);
235         setting_spinScaleFactor->setMaximum(1000);
236         setting_spinScaleFactor->setSingleStep(10);
237         setting_spinScaleFactor->setToolTip(tr("Scale factor"));
238         setting_spinScaleFactor->setValue(1000);
239         connect(setting_spinScaleFactor, SIGNAL(valueChanged(int)), this, SLOT(update()));
240         scaleFactorActionLayout->addWidget(setting_spinScaleFactor);
241
242         QWidget* scaleFactorActionWidget = new QWidget(&m_popup_menu);
243         scaleFactorActionWidget->setLayout(scaleFactorActionLayout);
244
245         QWidgetAction* scaleFactorAction = new QWidgetAction(&m_popup_menu);
246         scaleFactorAction->setDefaultWidget(scaleFactorActionWidget);
247         m_popup_menu.addAction(scaleFactorAction);
248
249         QHBoxLayout* durationActionLayout = new QHBoxLayout(&m_popup_menu);
250
251         QLabel* durationActionTitle = new QLabel(tr("Duration"), &m_popup_menu);
252         durationActionLayout->addWidget(durationActionTitle);
253
254         setting_spinDuration = new QSpinBox(&m_popup_menu);
255         setting_spinDuration->setMinimum(20);
256         setting_spinDuration->setMaximum(120000);
257         setting_spinDuration->setSingleStep(100);
258         setting_spinDuration->setToolTip(tr("Duration"));
259         setting_spinDuration->setValue(10000);
260         connect(setting_spinDuration, SIGNAL(valueChanged(int)), this, SLOT(update()));
261         durationActionLayout->addWidget(setting_spinDuration);
262
263         QWidget* durationActionWidget = new QWidget(&m_popup_menu);
264         durationActionWidget->setLayout(durationActionLayout);
265
266         QWidgetAction* durationAction = new QWidgetAction(&m_popup_menu);
267         durationAction->setDefaultWidget(durationActionWidget);
268         m_popup_menu.addAction(durationAction);
269
270         QHBoxLayout* maxHeightActionLayout = new QHBoxLayout(&m_popup_menu);
271
272         QLabel* maxHeightActionTitle = new QLabel(tr("Max height"), &m_popup_menu);
273         maxHeightActionLayout->addWidget(maxHeightActionTitle);
274
275         setting_spinMaxHeight = new QSpinBox(&m_popup_menu);
276         setting_spinMaxHeight->setMinimum(10);
277         setting_spinMaxHeight->setMaximum(100000);
278         setting_spinMaxHeight->setSingleStep(1);
279         setting_spinMaxHeight->setToolTip(tr("Max height"));
280         setting_spinMaxHeight->setValue(50);
281         maxHeightActionLayout->addWidget(setting_spinMaxHeight);
282
283         QWidget* maxHeightActionWidget = new QWidget(&m_popup_menu);
284         maxHeightActionWidget->setLayout(maxHeightActionLayout);
285
286         QWidgetAction* maxHeightAction = new QWidgetAction(&m_popup_menu);
287         maxHeightAction->setDefaultWidget(maxHeightActionWidget);
288         m_popup_menu.addAction(maxHeightAction);
289 }
290
291 void GLGraph::save()
292 {
293         s_settings->setValue("showWaveForm", setting_showWaveForm->isChecked());
294         s_settings->setValue("autoScale", setting_autoScale->isChecked());
295         s_settings->setValue("setting_spinScaleFactor", setting_spinScaleFactor->value());
296         s_settings->setValue("spinDuration", setting_spinDuration->value());
297         s_settings->setValue("spinMaxHeight", setting_spinMaxHeight->value());
298 }
299 void GLGraph::load()
300 {
301         setting_showWaveForm->setChecked(s_settings->value("showWaveForm", setting_showWaveForm->isChecked()).toBool());
302         setting_autoScale->setChecked(s_settings->value("autoScale", setting_autoScale->isChecked()).toBool());
303         setting_spinScaleFactor->setValue(s_settings->value("setting_spinScaleFactor", setting_spinScaleFactor->value()).toInt());
304         setting_spinDuration->setValue(s_settings->value("spinDuration", setting_spinDuration->value()).toInt());
305         setting_spinMaxHeight->setValue(s_settings->value("spinMaxHeight", setting_spinMaxHeight->value()).toInt());
306 }
307 void GLGraph::clearSettings()
308 {
309 //      cerr << "GLGraph::clearSettings" << endl;
310         s_settings->remove("showWaveForm");
311         s_settings->remove("autoScale");
312         s_settings->remove("setting_spinScaleFactor");
313         s_settings->remove("spinDuration");
314         s_settings->remove("spinMaxHeight");
315 }
316
317 void GLGraph::initializeGL()
318 {
319         // Set the clear color to white
320         glClearColor(1.0, 1.0, 1.0, 0.0);
321
322         // glShadeModel( GL_FLAT );
323         glShadeModel(GL_SMOOTH);
324
325         glEnable(GL_BLEND);
326         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
327
328         glLoadIdentity();
329 }
330
331 void GLGraph::resizeGL( int w, int h )
332 {
333         // Set the new viewport size
334         glViewport(0, 0, (GLint)w, (GLint)h);
335
336         // Choose the projection matrix to be the matrix
337         // manipulated by the following calls
338         glMatrixMode(GL_PROJECTION);
339
340         // Set the projection matrix to be the identity matrix
341         glLoadIdentity();
342
343         // Define the dimensions of the Orthographic Viewing Volume
344         glOrtho(0.0, w, 0.0, h, 0.0, 1.0);
345
346         // Choose the modelview matrix to be the matrix
347         // manipulated by further calls
348         glMatrixMode(GL_MODELVIEW);
349
350         update_maxs();
351 }
352
353 void GLGraph::addValue(double v)
354 {
355         m_pending_queue.push_front(v);
356         m_queue.push_front(v);
357
358         m_new_values = true;
359 }
360 void GLGraph::clearValues()
361 {
362         m_queue.clear();
363         m_maxs.clear();
364 }
365 void GLGraph::refreshGraph()
366 {
367         int max_size = getLength();
368         m_skip = max_size/width();
369         if(m_skip<1)    m_skip = 1;
370
371         while(!m_pending_queue.empty() && int(m_pending_queue.size()) >= m_skip)
372         {
373                 double smin = m_pending_queue.back();
374                 double smax = m_pending_queue.back();
375                 for(int i=0; i<m_skip; i++)
376                 {
377                         m_queue.push_front(m_pending_queue.back());
378                         smin = min(smin, m_pending_queue.back());
379                         smax = max(smax, m_pending_queue.back());
380                         m_pending_queue.pop_back();
381                 }
382                 m_maxs.push_front(make_pair(smin, smax));
383         }
384
385         // drop unused data
386         while(!m_maxs.empty() && int(m_maxs.size())>=width())
387                 m_maxs.pop_back();
388
389         // drop unused data
390         while(!m_queue.empty() && int(m_queue.size())>max_size)
391                 m_queue.pop_back();
392
393         m_new_values = false;
394 }
395
396 void GLGraph::update_maxs()
397 {
398 //      cerr << "GLGraph::update_maxs " << m_sampling_rate << endl;
399
400         if(m_queue.empty())     return;
401
402         m_maxs.clear();
403         int max_size = getLength();
404         m_skip = max_size/width();
405         if(m_skip<1)    m_skip = 1;
406
407         // drop unused data
408         while(!m_queue.empty() && int(m_queue.size())>max_size)
409                 m_queue.pop_back();
410
411         // computes maxs
412         for(size_t j=0; j+m_skip<=m_queue.size(); j+=m_skip)
413         {
414                 double smin, smax;
415                 smin = smax = m_queue[j+m_skip];
416                 for(size_t i=j; i<j+m_skip && i<m_queue.size(); i++)
417                 {
418                         smin = min(smin, m_queue[i]);
419                         smax = max(smax, m_queue[i]);
420                 }
421                 m_maxs.push_back(make_pair(smin, smax));
422         }
423
424         updateGL();
425 }
426
427 void GLGraph::base_paint(float graph_gray)
428 {
429 //      cerr << "GLGraph::base_paint " << m_queue.size() << ":" << m_maxs.size() << endl;
430
431 //      cerr<<"m_pending_queue="<<m_pending_queue.size()<<" m_queue="<<m_queue.size()<<" m_maxs="<<m_maxs.size()<<endl;
432
433         int width = QGLWidget::width();
434
435         // name
436         string str = tr("Captured Sound").toStdString();
437         glColor3f(0.75,0.75,0.75);
438         glRasterPos2i(2, height()-14);
439         for(size_t i = 0; i < str.size(); i++)
440                 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, (unsigned char)str[i]);
441
442         if(setting_showWaveForm->isChecked() && !m_queue.empty())
443         {
444                 // horiz line
445                 glBegin(GL_LINES);
446                 float gray = 0.8;
447                 glColor3f(gray, gray, gray);
448                 glVertex2i(0, height()/2);
449                 glVertex2i(width, height()/2);
450                 glEnd();
451
452                 m_queue_amplitude = 0.0;
453                 double scale_factor;
454                 if(setting_autoScale->isChecked())
455                 {
456                         if(m_skip<2)
457                                 for(size_t i=0; i<m_queue.size(); i++)
458                                         m_queue_amplitude = max(m_queue_amplitude, abs(m_queue[i]));
459                         else
460                                 for(size_t i=0; i<m_maxs.size(); i++)
461                                         m_queue_amplitude = max(m_queue_amplitude, max(-m_maxs[i].first,m_maxs[i].second));
462                         scale_factor = 1.0/m_queue_amplitude;
463                 }
464                 else
465                         scale_factor = 1000.0/setting_spinScaleFactor->value();
466
467                 // paint the noise treshold
468                 glBegin(GL_LINES);
469                 int y = int((1+m_treshold*scale_factor)*height()/2);
470                 glColor3f(1.0,1.0,1.0);
471                 glVertex2i(0, y);
472                 glColor3f(1.0,0.5,0.5);
473                 glVertex2i(width, y);
474                 y = int((1-m_treshold*scale_factor)*height()/2);
475                 glColor3f(1.0,1.0,1.0);
476                 glVertex2i(0, y);
477                 glColor3f(1.0,0.5,0.5);
478                 glVertex2i(width, y);
479                 glEnd();
480
481                 // paint the wave form
482                 glColor3f(graph_gray, graph_gray, graph_gray);
483                 if(m_skip<2)
484                 {
485                         glBegin(GL_LINE_STRIP);
486
487                         glVertex2i(width-1, int((m_queue[0]*scale_factor)*height()/2 + height()/2));
488                         float istep = float(width)/m_queue.size();
489                         for(size_t i=1; i<m_queue.size(); i++)
490                                 glVertex2i(width-1-int(i*istep), int((m_queue[i]*scale_factor)*height()/2 + height()/2));
491
492                         glEnd();
493                 }
494                 else
495                 {
496                         glBegin(GL_LINES);
497                         for(size_t i=0; i<m_maxs.size(); i++)
498                         {
499                                 int x = width-1-i;
500                                 int ymin = int((m_maxs[i].first*scale_factor)*height()/2 + height()/2);
501                                 int ymax = int((m_maxs[i].second*scale_factor)*height()/2 + height()/2);
502                                 glVertex2i(x, ymin);
503                                 glVertex2i(x, ymax);
504                         }
505                         glEnd();
506                 }
507         }
508 }
509
510 void GLGraph::paintGL()
511 {
512         if(m_new_values)
513                 refreshGraph();
514
515         glClear(GL_COLOR_BUFFER_BIT);
516
517         base_paint();
518
519         glFlush();
520 }
521