7 #include <Xm/RowColumn.h>
10 #include <curl/curl.h>
17 char *days[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
22 printf("ERROR: Out of memory\n");
28 memback(void *contents, size_t size, size_t nmemb, void *userp)
30 size_t realsize = size * nmemb;
31 struct memstruct *mem = (struct memstruct *)userp;
33 char *ptr = realloc(mem->memory, mem->size + realsize + 1);
37 memcpy(&(mem->memory[mem->size]), contents, realsize);
38 mem->size += realsize;
39 mem->memory[mem->size] = 0;
47 CURL *curl = curl_easy_init();
51 fprintf(stderr, "ERROR: Failed to initialize cURL\n");
55 struct memstruct chunk;
56 chunk.memory = malloc(1); // Grown as needed by the realloc in memback()
57 chunk.size = 0; // No data yet
60 "https://nobilis.nobles.edu/skyworld/castlemenu.php?Date=";
61 int len = strlen(baseurl) + strlen(date) + 1;
62 char *url = (char *)malloc(len);
63 snprintf(url, len, "%s%s", baseurl, date);
64 printf("INFO: Using URL %s\n", url);
65 curl_easy_setopt(curl, CURLOPT_URL, url);
66 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memback);
67 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
68 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
70 printf("INFO: Fetching wepage\n");
71 res = curl_easy_perform(curl);
74 if (res != CURLE_OK) {
75 fprintf(stderr,"ERROR: Could not fetch webpage\n%s\n",
76 curl_easy_strerror(res));
80 curl_easy_cleanup(curl);
83 printf("INFO: Parsing HTML\n");
85 char *outp = (char *) calloc(1, sizeof(char));
88 // Extract text from between HTML tags
92 for (int i = 345; chunk.memory[i]; i++) {
93 char c = chunk.memory[i];
94 if (c == '<') intag = true;
97 outp = (char *) realloc(outp, j);
100 strncat(outp, next, 2);
102 if (c == '>') intag = false;
105 // Strip empty newlines
106 char *nl = (char *) calloc(1, sizeof(char));
110 for (int i = 0; outp[i]; i++) {
112 if (outp[i] == '\n' && outp[i+1] == '\n') i+=3;
113 nl = (char *) realloc(nl, j);
116 strncat(nl, next, 2);
123 dayback(Widget w, XtPointer client_data, XtPointer call_data)
125 Widget text_w = (Widget) client_data;
126 XmListCallbackStruct *list_cbs = (XmListCallbackStruct *) call_data;
127 char *nl = getmenu(days[list_cbs->item_position - 1]);
128 XmTextReplace((Widget) text_w, 0, strlen(XmTextGetString(text_w)), nl);
131 /* Convert an array of string to an array of compound strings */
132 XmStringTable ArgvToXmStringTable (int argc, char **argv)
135 (XmStringTable) XtMalloc ((argc+1) * sizeof (XmString));
137 return (XmStringTable) 0;
138 new[argc] = (XmString) 0;
140 new[argc] = XmStringGenerate ((XtPointer) argv[argc], "tag2",
141 XmCHARSET_TEXT, NULL);
146 main(int argc, char *argv[])
149 Widget toplevel, rowcol, w, text_w;
154 XtSetLanguageProc(NULL, NULL, NULL);
155 toplevel = XtVaOpenApplication(&app, "Castle Menu", NULL, 0, &argc, argv,
156 NULL, sessionShellWidgetClass, NULL);
159 XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
160 rowcol = XmCreateRowColumn(toplevel, "rowcol", args, n);
162 // Create text widget to display menu
164 char *nl = getmenu("");
165 XtSetArg(args[n], XmNvalue, nl); n++;
166 XtSetArg(args[n], XmNeditable, False); n++;
167 XtSetArg(args[n], XmNcolumns, 80); n++;
168 XtSetArg(args[n], XmNcursorPositionVisible, False); n++;
169 text_w = XmCreateScrolledText(rowcol, "text", args, n);
170 XtManageChild(text_w);
172 // Create day selector
173 strs = ArgvToXmStringTable (XtNumber (days), days);
174 w = XmCreateScrolledList(rowcol, "list", NULL, 0);
177 XmNitemCount, XtNumber (days),
179 XtAddCallback(w, XmNbrowseSelectionCallback, dayback, (XtPointer) text_w);
181 XtManageChild(rowcol);
183 // Display everything
184 XtRealizeWidget(toplevel);