1#include <gtk/gtk.h> 2#include <libwebsockets.h> 3 4static int status = 0; 5 6static void 7print_hello(GtkWidget *widget, gpointer data) 8{ 9 g_print("Hello World\n"); 10} 11 12static void 13activate(GtkApplication *app, gpointer user_data) 14{ 15 GtkWidget *window; 16 GtkWidget *button, *bbox; 17 18 window = gtk_application_window_new(app); 19 gtk_window_set_title(GTK_WINDOW(window), "mywindow"); 20 gtk_window_set_default_size(GTK_WINDOW(window), 200, 200); 21 22 bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); 23 gtk_container_add(GTK_CONTAINER(window), bbox); 24 25 button = gtk_button_new_with_label("Hello World"); 26 g_signal_connect(button, "clicked", G_CALLBACK(print_hello), NULL); 27 g_signal_connect_swapped(button, "clicked", 28 G_CALLBACK(gtk_widget_destroy), window); 29 gtk_container_add(GTK_CONTAINER(bbox), button); 30 31 gtk_widget_show_all(window); 32} 33 34static int 35system_notify_cb(lws_state_manager_t *mgr, lws_state_notify_link_t *link, 36 int current, int target) 37{ 38 struct lws_context *context = mgr->parent; 39 struct lws_client_connect_info i; 40 41 if (current != LWS_SYSTATE_OPERATIONAL || 42 target != LWS_SYSTATE_OPERATIONAL) 43 return 0; 44 45 lwsl_notice("%s: operational\n", __func__); 46 47 memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ 48 i.context = context; 49 i.ssl_connection = LCCSCF_USE_SSL | LCCSCF_H2_QUIRK_OVERFLOWS_TXCR | 50 LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM; 51 i.port = 443; 52 i.address = "warmcat.com"; 53 i.path = "/"; 54 i.host = i.address; 55 i.origin = i.address; 56 i.method = "GET"; 57 58 i.protocol = "http"; 59 60 return !lws_client_connect_via_info(&i); 61} 62 63static int 64callback_http(struct lws *wsi, enum lws_callback_reasons reason, 65 void *user, void *in, size_t len) 66{ 67 switch (reason) { 68 69 /* because we are protocols[0] ... */ 70 case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: 71 lwsl_err("CLIENT_CONNECTION_ERROR: %s\n", 72 in ? (char *)in : "(null)"); 73 break; 74 75 case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: 76 { 77 char buf[128]; 78 79 lws_get_peer_simple(wsi, buf, sizeof(buf)); 80 status = lws_http_client_http_response(wsi); 81 82 lwsl_user("Connected to %s, http response: %d\n", 83 buf, status); 84 } 85 break; 86 87 /* chunks of chunked content, with header removed */ 88 case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: 89 lwsl_user("RECEIVE_CLIENT_HTTP_READ: read %d\n", (int)len); 90 return 0; /* don't passthru */ 91 92 /* uninterpreted http content */ 93 case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: 94 { 95 char buffer[1024 + LWS_PRE]; 96 char *px = buffer + LWS_PRE; 97 int lenx = sizeof(buffer) - LWS_PRE; 98 99 if (lws_http_client_read(wsi, &px, &lenx) < 0) 100 return -1; 101 } 102 return 0; /* don't passthru */ 103 104 case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: 105 lwsl_user("LWS_CALLBACK_COMPLETED_CLIENT_HTTP\n"); 106 lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */ 107 break; 108 109 case LWS_CALLBACK_CLOSED_CLIENT_HTTP: 110 lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */ 111 break; 112 113 default: 114 break; 115 } 116 117 return lws_callback_http_dummy(wsi, reason, user, in, len); 118} 119 120static const struct lws_protocols protocols[] = { 121 { 122 "http", 123 callback_http, 124 0, 125 0, 126 }, 127 { NULL, NULL, 0, 0 } 128}; 129 130static gpointer 131t1_main (gpointer user_data) 132{ 133 lws_state_notify_link_t notifier = { { NULL, NULL, NULL }, 134 system_notify_cb, "app" }; 135 lws_state_notify_link_t *na[] = { ¬ifier, NULL }; 136 GMainContext *t1_mc = (GMainContext *)user_data; 137 struct lws_context_creation_info info; 138 struct lws_context *context; 139 void *foreign_loops[1]; 140 GMainLoop *ml; 141 142 g_print("%s: started\n", __func__); 143 144 g_main_context_push_thread_default(t1_mc); 145 146 ml = g_main_loop_new(t1_mc, FALSE); 147 148 /* attach our lws activities to the main loop of this thread */ 149 150 lws_set_log_level(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE, NULL); 151 memset(&info, 0, sizeof info); 152 info.port = CONTEXT_PORT_NO_LISTEN; 153 info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | 154 LWS_SERVER_OPTION_GLIB; 155 info.protocols = protocols; 156 foreign_loops[0] = (void *)ml; 157 info.foreign_loops = foreign_loops; 158 info.register_notifier_list = na; 159 160#if defined(LWS_WITH_MBEDTLS) || defined(USE_WOLFSSL) 161 /* 162 * OpenSSL uses the system trust store. mbedTLS has to be told which 163 * CA to trust explicitly. 164 */ 165 info.client_ssl_ca_filepath = "./warmcat.com.cer"; 166#endif 167 168 context = lws_create_context(&info); 169 if (!context) { 170 lwsl_err("lws init failed\n"); 171 return NULL; 172 } 173 174 /* 175 * We created the lws_context and bound it to this thread's main loop, 176 * let's run the thread's main loop now... 177 */ 178 179 g_main_loop_run(ml); 180 g_main_loop_unref(ml); 181 182 g_main_context_pop_thread_default(t1_mc); 183 g_main_context_unref(t1_mc); 184 185 g_print("%s: ending\n", __func__); 186 187 lws_context_destroy(context); 188 189 return NULL; 190} 191 192int 193main(int argc, char **argv) 194{ 195 GMainContext *t1_mc = g_main_context_new(); 196 GtkApplication *app; 197 GThread *t1; 198 int status; 199 200 t1 = g_thread_new ("t1", t1_main, g_main_context_ref (t1_mc)); 201 (void)t1; 202 203 app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE); 204 g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); 205 206 status = g_application_run(G_APPLICATION(app), argc, argv); 207 g_object_unref(app); 208 209 return status; 210} 211 212