add playlist data structure
[uwplayer.git] / application / Sidebar.c
1 /*
2  * Copyright 2022 Olaf Wintermann
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a 
5  * copy of this software and associated documentation files (the "Software"), 
6  * to deal in the Software without restriction, including without limitation 
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
8  * and/or sell copies of the Software, and to permit persons to whom the 
9  * Software is furnished to do so, subject to the following conditions:
10  * 
11  * The above copyright notice and this permission notice shall be included in 
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
20  * DEALINGS IN THE SOFTWARE.
21  */
22
23 #include "Sidebar.h"
24 #include "SidebarP.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30
31 #include "xdnd.h"
32
33
34 static void sidebar_class_init(void);
35 static void sidebar_class_part_init (WidgetClass wc);
36 static void sidebar_init(Widget request, Widget neww, ArgList args, Cardinal *num_args);
37 static void sidebar_destroy(Widget widget);
38 static void sidebar_resize(Widget widget);
39 static void sidebar_realize(Widget widget, XtValueMask *mask, XSetWindowAttributes *attributes);
40 static void sidebar_expose(Widget widget, XEvent *event, Region region);
41 static Boolean sidebar_set_values(Widget old, Widget request, Widget neww, ArgList args, Cardinal *num_args);
42 static void sidebar_insert_child(Widget child);
43 Boolean sidebar_acceptfocus(Widget widget, Time *time);
44 static void FocusInAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
45
46 static void xdndEnterAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
47
48 static void sidebar_xdnd_callback(Widget w, XtPointer udata, XtPointer cdata);
49
50
51 static XtResource resources[] = {
52
53 };
54
55 static XtActionsRec actionslist[] = {
56   {"focusIn", FocusInAP},
57   {"xdnd_enter", xdndEnterAP},
58   {"NULL", NULL}
59 };
60
61 static char defaultTranslations[] = "<FocusIn>:                 focusIn()\n"
62                                     "<Message>XdndEnter:    xdnd_enter()\n";
63
64
65 static XtResource constraints[] = {};
66
67 SidebarClassRec sidebarWidgetClassRec = {
68     // Core Class
69     {
70         (WidgetClass)&xmManagerClassRec,
71         "XnSidebar",                         // class_name
72         sizeof(SidebarRec),                  // widget_size
73         sidebar_class_init,                  // class_initialize
74         sidebar_class_part_init,             // class_part_initialize
75         FALSE,                           // class_inited
76         sidebar_init,                        // initialize
77         NULL,                            // initialize_hook
78         sidebar_realize,                     // realize
79         actionslist,                     // actions
80         XtNumber(actionslist),           // num_actions
81         resources,                       // resources
82         XtNumber(resources),             // num_resources
83         NULLQUARK,                       // xrm_class
84         True,                            // compress_motion
85         True,                            // compress_exposure
86         True,                            // compress_enterleave
87         False,                           // visible_interest
88         sidebar_destroy,                     // destroy
89         sidebar_resize,                      // resize
90         sidebar_expose,                 // expose
91         sidebar_set_values,                  // set_values
92         NULL,                            // set_values_hook
93         XtInheritSetValuesAlmost,        // set_values_almost
94         NULL,                            // get_values_hook
95         sidebar_acceptfocus,                 // accept_focus
96         XtVersion,                       // version
97         NULL,                            // callback_offsets
98         defaultTranslations,             // tm_table
99         XtInheritQueryGeometry,          // query_geometry
100         XtInheritDisplayAccelerator,     // display_accelerator
101         NULL,                            // extension
102     },
103     // Composite Class
104     {
105         XtInheritGeometryManager, // geometry_manager 
106         XtInheritChangeManaged,   // change_managed
107         sidebar_insert_child,         // insert_child 
108         XtInheritDeleteChild,     // delete_child  
109         NULL,                     // extension   
110     },
111     // Constraint Class
112     {
113         constraints,                 // resources
114         XtNumber(constraints),       // num_resources   
115         sizeof(XmFormConstraintRec), // constraint_size  
116         NULL,                        // initialize 
117         NULL,                        // destroy
118         NULL,                        // set_value
119         NULL,                        // extension 
120     },
121     // XmManager Class
122     {
123         XtInheritTranslations, // translations
124         NULL, // syn_resources
125         0,    // num_syn_resources
126         NULL, // syn_constraint_resources
127         0,    // num_syn_constraint_resources
128         XmInheritParentProcess, // parent_process
129         NULL  // extension
130     },
131     // Sidebar Class
132     {
133         0
134     }
135 };
136
137 WidgetClass xnSidebarWidgetClass = (WidgetClass)&sidebarWidgetClassRec;
138
139
140 static void sidebar_class_init(void) {
141
142 }
143
144 static void sidebar_class_part_init (WidgetClass wc) {
145     SidebarClassRec *sidebarClass = (SidebarClassRec*)wc;
146     XmManagerClassRec *managerClass = (XmManagerClassRec*)xmManagerWidgetClass;
147     
148     sidebarClass->constraint_class.initialize = managerClass->constraint_class.initialize;
149     sidebarClass->constraint_class.set_values = managerClass->constraint_class.set_values;
150 }
151
152
153
154 static void sidebar_init(Widget request, Widget neww, ArgList args, Cardinal *num_args) {
155     
156 }
157
158
159
160 static void sidebar_destroy(Widget widget) {
161     
162 }
163
164 static void sidebar_resize(Widget widget) {
165     
166 }
167
168 static int xdnd_initialized = 0;
169
170 static void sidebar_realize(Widget widget, XtValueMask *mask, XSetWindowAttributes *attributes) {
171     (xmManagerClassRec.core_class.realize)(widget, mask, attributes);
172     
173     if(!xdnd_initialized) {
174         XdndInit(XtDisplay(widget), XtWidgetToApplicationContext(widget), sidebar_xdnd_callback, widget);
175     }
176     XdndEnable(widget);
177 }
178
179 static void sidebar_expose(Widget widget, XEvent *event, Region region) {
180     printf("expose\n");
181     Dimension w, h;
182     XtMakeResizeRequest(widget, 200, 200, &w, &h);
183 }
184
185 static Boolean sidebar_set_values(Widget old, Widget request, Widget neww, ArgList args, Cardinal *num_args) {
186     Boolean r = False;
187
188     return r;
189 }
190
191 static void sidebar_insert_child(Widget child) {
192     (xmManagerClassRec.composite_class.insert_child)(child);
193 }
194
195 Boolean sidebar_acceptfocus(Widget widget, Time *time) {
196     return 0;
197 }
198
199
200 static void FocusInAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
201     printf("focusin\n");
202     fflush(stdout);
203 }
204
205 static void xdndEnterAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
206     printf("xdndEnterAP\n");
207     fflush(stdout);
208 }
209
210
211
212
213 static void sidebar_xdnd_callback(Widget w, XtPointer udata, XtPointer cdata) {
214     printf("xdnd\n");
215     fflush(stdout);
216     
217     char *urilist = udata;
218     
219     size_t len = strlen(urilist);
220     
221     size_t start = 0;
222     if(len > 7 && !memcmp(urilist, "file://", 7)) {
223         start = 7;
224     }
225     
226     int err = 0;
227     
228     // urldecode
229     char *path = malloc(len + 1);
230     int k = 0;
231     for(int i=start;i<len;i++) {
232         char c = urilist[i];
233         if(c == '%') {
234             if(i + 2 < len) {
235                 char code[3];
236                 code[0] = urilist[i+1];
237                 code[1] = urilist[i+2];
238                 code[2] = '\0';
239                 
240                 errno = 0;
241                 char *end = NULL;
242                 int ascii = (int)strtol(code, &end, 16);
243                 if(errno == 0 && end == &code[2]) {
244                     path[k] = ascii;
245                     i += 2;
246                 } else {
247                     err = 1;
248                     break;
249                 }
250             } else {
251                 err = 1;
252                 break;
253             }
254         } else if(c == '\n' || c == '\r') {
255             break;
256         } else {
257             path[k] = c;
258         }
259         
260         k++;
261     }
262     path[k] = '\0';
263     
264     // add file
265     // TODO
266     
267     free(path);
268 }
269
270
271 /* --------------------------- public --------------------------- */
272
273 Widget CreateSidebar(
274         Widget parent,
275         String name,
276         ArgList arglist,
277         Cardinal argcount)
278 {
279     return XtCreateWidget(name, xnSidebarWidgetClass, parent, arglist, argcount);
280 }