infopanel.c (8485B)
1 #include <string.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 #include "app.h" 6 #include "infopanel.h" 7 8 #include "config.h" 9 10 #define KERNEL_NAME_MAX 512 11 #define KERNEL_RELEASE_MAX 512 12 #define MEM_FREE_MAX 512 13 #define UPTIME_MAX 512 14 15 static struct WMInfoPanel* ip = NULL; 16 static char kernel_name[KERNEL_NAME_MAX]; 17 static char kernel_release[KERNEL_RELEASE_MAX]; 18 static char mem_free[MEM_FREE_MAX]; 19 static char uptime[UPTIME_MAX]; 20 21 void 22 close_info_panel(WMWidget* self, void* data) 23 { 24 struct WMInfoPanel* ip = (struct WMInfoPanel*)data; 25 ip->done = 1; 26 } 27 28 static char* 29 get_kernel_name() 30 { 31 FILE* uname = NULL; 32 char* eol = NULL; 33 34 if (*kernel_name) 35 return kernel_name; 36 37 if (!(uname = popen("uname -s", "r"))) 38 strcpy(kernel_name, "(Unknown kernel)"); 39 else 40 { 41 fgets(kernel_name, KERNEL_NAME_MAX, uname); 42 eol = strchr(kernel_name, '\n'); 43 if (eol) 44 *eol = 0; 45 pclose(uname); 46 } 47 48 return kernel_name; 49 } 50 51 static char* 52 get_kernel_release() 53 { 54 FILE* uname = NULL; 55 char* eol = NULL; 56 57 if (*kernel_release) 58 return kernel_release; 59 60 if (!(uname = popen("uname -r", "r"))) 61 strcpy(kernel_release, "(Unknown release)"); 62 else 63 { 64 fgets(kernel_release, KERNEL_RELEASE_MAX, uname); 65 eol = strchr(kernel_release, '\n'); 66 if (eol) 67 *eol = 0; 68 pclose(uname); 69 } 70 71 return kernel_release; 72 } 73 74 static char* 75 get_mem_free() 76 { 77 FILE* cmd = NULL; 78 char* eol = NULL; 79 80 if (!(cmd = popen("free -g | awk '/^(Mem|Swap)/ { f += $4 } " 81 "END {print f}'", 82 "r"))) 83 strcpy(mem_free, "N/A"); 84 else 85 { 86 fgets(mem_free, MEM_FREE_MAX, cmd); 87 eol = strchr(mem_free, '\n'); 88 if (eol) 89 *eol = 0; 90 pclose(cmd); 91 } 92 93 return mem_free; 94 } 95 96 static char* 97 get_uptime() 98 { 99 FILE* cmd = NULL; 100 char* eol = NULL; 101 102 if (!(cmd = popen("uptime | awk '{gsub(\",\", \"\", $3); print $3}'", 103 "r"))) 104 strcpy(uptime, "N/A"); 105 else 106 { 107 fgets(uptime, UPTIME_MAX, cmd); 108 eol = strchr(uptime, '\n'); 109 if (eol) 110 *eol = 0; 111 pclose(cmd); 112 } 113 114 return uptime; 115 } 116 117 #define LABEL_BUF_MAX 512 118 119 static struct WMInfoPanel* 120 create_info_panel(struct WMNewApp* wma) 121 { 122 struct WMInfoPanel* ip = NULL; 123 WMSize icon_size; 124 WMFont* title_font; 125 WMFont* bold_font; 126 WMFont* normal_font; 127 int offset, width, height; 128 int title_width; 129 int icon_frame_offset; 130 int icon_frame_width, icon_frame_height; 131 int info_frame_offset, info_frame_second_col_offset; 132 int info_frame_width, info_frame_height; 133 int info_offset_delta; 134 int padding; 135 char buffer[LABEL_BUF_MAX]; 136 137 if (!(ip = (struct WMInfoPanel*)calloc(sizeof(struct WMInfoPanel), 1))) 138 exit(error(1, "calloc failed")); 139 memset((void*)ip, 0, sizeof(struct WMInfoPanel)); 140 141 width = 500; 142 height = 300; 143 padding = 15; 144 145 title_font = WMBoldSystemFontOfSize(wma->scr, 24); 146 bold_font = WMBoldSystemFontOfSize(wma->scr, 12); 147 normal_font = WMSystemFontOfSize(wma->scr, 12); 148 149 ip->app = wma; 150 ip->window = WMCreateWindow(wma->scr, "info"); 151 WMResizeWidget(ip->window, width, height); 152 WMSetWindowTitle(ip->window, "Info"); 153 WMSetWindowCloseAction(ip->window, close_info_panel, ip); 154 155 offset = padding; 156 title_width = WMWidthOfString(title_font, program_name, 157 strlen(program_name)); 158 159 icon_size = WMGetPixmapSize(wma->wmpixmap); 160 icon_frame_width = width - 2 * padding; 161 icon_frame_height = icon_size.height + padding + 24; 162 163 /* / Icon frame \ */ 164 icon_frame_offset = 0; 165 166 ip->icon_frame = WMCreateFrame(ip->window); 167 WMMoveWidget(ip->icon_frame, padding, offset); 168 WMResizeWidget(ip->icon_frame, icon_frame_width, icon_frame_height); 169 WMSetFrameRelief(ip->icon_frame, WRFlat); 170 171 ip->icon_label = WMCreateLabel(ip->icon_frame); 172 WMResizeWidget(ip->icon_label, icon_size.width, icon_size.height); 173 WMMoveWidget(ip->icon_label, (icon_frame_width - icon_size.width) / 2, 174 icon_frame_offset); 175 WMSetLabelImage(ip->icon_label, wma->wmpixmap); 176 WMSetLabelImagePosition(ip->icon_label, WIPImageOnly); 177 icon_frame_offset += icon_size.height + padding; 178 179 ip->title_label = WMCreateLabel(ip->icon_frame); 180 WMMoveWidget(ip->title_label, (icon_frame_width - title_width) / 2, 181 icon_frame_offset); 182 WMResizeWidget(ip->title_label, icon_frame_width, 24); 183 WMSetLabelText(ip->title_label, program_name); 184 WMSetLabelFont(ip->title_label, title_font); 185 /* \ Icon frame / */ 186 187 offset += icon_frame_height + padding; 188 189 ip->author_label = WMCreateLabel(ip->window); 190 WMMoveWidget(ip->author_label, padding, offset); 191 WMResizeWidget(ip->author_label, icon_frame_width, 12); 192 WMSetLabelTextAlignment(ip->author_label, WACenter); 193 snprintf(buffer, LABEL_BUF_MAX, "by %s", program_author); 194 WMSetLabelText(ip->author_label, buffer); 195 WMSetLabelFont(ip->author_label, normal_font); 196 offset += 12 + padding; 197 198 /* / Info frame \ */ 199 info_frame_width = icon_frame_width; 200 info_frame_height = height - offset - (12 + padding) - padding; 201 202 ip->info_frame = WMCreateFrame(ip->window); 203 WMMoveWidget(ip->info_frame, padding, offset); 204 WMResizeWidget(ip->info_frame, info_frame_width, info_frame_height); 205 // WMSetFrameRelief(ip->info_frame, WRGroove); 206 207 info_frame_offset = padding; 208 info_offset_delta = (info_frame_height - 4 * padding) / 3 + padding; 209 info_frame_second_col_offset = info_frame_width / 2 - 2 * padding; 210 211 ip->sys_release_label = WMCreateLabel(ip->info_frame); 212 WMMoveWidget(ip->sys_release_label, padding, info_frame_offset); 213 WMResizeWidget(ip->sys_release_label, info_frame_second_col_offset, 12); 214 snprintf(buffer, LABEL_BUF_MAX, "Kernel Release %s %s", 215 get_kernel_name(), get_kernel_release()); 216 WMSetLabelText(ip->sys_release_label, buffer); 217 WMSetLabelFont(ip->sys_release_label, normal_font); 218 219 ip->mem_free_label = WMCreateLabel(ip->info_frame); 220 WMMoveWidget(ip->mem_free_label, 221 padding + info_frame_second_col_offset + 2 * padding, 222 info_frame_offset); 223 WMResizeWidget(ip->mem_free_label, info_frame_second_col_offset, 12); 224 snprintf(buffer, LABEL_BUF_MAX, "Mem free: %s GB", get_mem_free()); 225 WMSetLabelText(ip->mem_free_label, buffer); 226 WMSetLabelTextAlignment(ip->mem_free_label, WARight); 227 WMSetLabelFont(ip->mem_free_label, normal_font); 228 info_frame_offset += info_offset_delta; 229 230 ip->app_release_label = WMCreateLabel(ip->info_frame); 231 WMMoveWidget(ip->app_release_label, padding, info_frame_offset); 232 WMResizeWidget(ip->app_release_label, 233 (info_frame_width - 2 * padding) / 2, 12); 234 snprintf(buffer, LABEL_BUF_MAX, "%s Release %s", program_name, 235 program_version); 236 WMSetLabelText(ip->app_release_label, buffer); 237 WMSetLabelFont(ip->app_release_label, normal_font); 238 239 ip->uptime_label = WMCreateLabel(ip->info_frame); 240 WMMoveWidget(ip->uptime_label, 241 padding + info_frame_second_col_offset + 2 * padding, 242 info_frame_offset); 243 WMResizeWidget(ip->uptime_label, info_frame_second_col_offset, 12); 244 snprintf(buffer, LABEL_BUF_MAX, "Uptime: %s", get_uptime()); 245 WMSetLabelText(ip->uptime_label, buffer); 246 WMSetLabelTextAlignment(ip->uptime_label, WARight); 247 WMSetLabelFont(ip->uptime_label, normal_font); 248 info_frame_offset += info_offset_delta; 249 250 ip->win_server_label = WMCreateLabel(ip->info_frame); 251 WMMoveWidget(ip->win_server_label, padding, info_frame_offset); 252 WMResizeWidget(ip->win_server_label, 253 (info_frame_width - 2 * padding) / 2, 12); 254 snprintf(buffer, LABEL_BUF_MAX, "Window Server %d", 255 VendorRelease(ip->app->dpy)); 256 WMSetLabelText(ip->win_server_label, buffer); 257 WMSetLabelFont(ip->win_server_label, normal_font); 258 /* \ Info frame / */ 259 260 offset += info_frame_height + padding; 261 262 ip->copy_label = WMCreateLabel(ip->window); 263 WMMoveWidget(ip->copy_label, padding, offset); 264 WMResizeWidget(ip->copy_label, width - 2 * padding, 12); 265 snprintf(buffer, LABEL_BUF_MAX, "Copyright (C) %s %s", copy_years, 266 copy_holder); 267 WMSetLabelText(ip->copy_label, buffer); 268 WMSetLabelTextColor(ip->copy_label, 269 WMCreateNamedColor(ip->app->scr, "dimgray", True)); 270 WMSetLabelTextAlignment(ip->copy_label, WACenter); 271 WMSetLabelFont(ip->copy_label, bold_font); 272 273 WMRealizeWidget(ip->window); 274 WMMapSubwidgets(ip->icon_frame); 275 WMMapSubwidgets(ip->info_frame); 276 WMMapSubwidgets(ip->window); 277 // WMMapWidget(ip->window); 278 WMReleaseFont(title_font); 279 WMReleaseFont(normal_font); 280 281 return ip; 282 } 283 284 static void 285 destroy_info_panel(struct WMInfoPanel* ip) 286 { 287 WMUnmapWidget(ip->window); 288 WMDestroyWidget(ip->window); 289 free((void*)ip); 290 ip = NULL; 291 } 292 293 void 294 run_info_panel(struct WMNewApp* wma) 295 { 296 if (!(ip = create_info_panel(wma))) 297 exit(error(1, "create_info_panel failed")); 298 299 WMMapWidget(ip->window); 300 301 while (!(ip->done)) 302 { 303 XEvent event; 304 WMNextEvent(ip->app->dpy, &event); 305 WMHandleEvent(&event); 306 } 307 destroy_info_panel(ip); 308 }