/* Copyright (c) 2000 Linus Nilsson <d96ln@efd.lth.se> */
#include "yawm.h"
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#define EDGE_SPACE (opt_bw + 1)
#define FONT_YOFF (TASKBAR_HEIGHT/2 - opt_bw/2 + (font->ascent+font->descent)/2)
void draw_bartime(char *thestring) {
if (!thestring) {
debug("The argument to draw_bartime was NULL!\n");
exit(1);
}
/* Add double buffering later */
XClearArea(child_dpy, taskbar,
DisplayWidth(child_dpy, 0) -
XTextWidth(font, thestring, strlen(thestring)) - EDGE_SPACE,
TASKBAR_HEIGHT/2 - (font->ascent + font->descent)/2,
XTextWidth(font, thestring, strlen(thestring)),
(font->ascent + font->descent),
False);
XDrawString(child_dpy, taskbar, taskbar_focus_fg_gc,
DisplayWidth(child_dpy, 0) - opt_bw - 4 -
XTextWidth(font, thestring, strlen(thestring)) -
EDGE_SPACE,
FONT_YOFF,
thestring, strlen(thestring));
XSync(child_dpy, False);
}
int count_tasks(void) {
Client *c = (Client *) malloc (sizeof(Client));
int n = 0;
for (c = head_client; c; c = c->next) {
n++;
}
return n;
}
void draw_tasks(void) {
char *tasks_string = (char *) malloc(1024);
Client *c = (Client *) malloc (sizeof(Client));
int offset = opt_bw + 1;
debug("entered draw_tasks()\n");
for (c = head_client; c != NULL; c = c->next) {
debug("loop1");
if (!c->window) {
remove_client(c, 0);
}
else {
XFetchName(dpy, c->window, &c->barname);
redraw(c);
}
}
while (find_width() > DisplayWidth(dpy, 0) - 200 &&
count_tasks() <= MAX_CLIENTS_ON_TASKBAR &&
(c ? strcmp(c->barname, "...") != 0 : 1)) {
debug("loop2");
c = find_client_with_longest_name();
dec_barname(find_client_with_longest_name());
}
XClearArea(dpy, taskbar, opt_bw, opt_bw,
DisplayWidth(dpy, 0) - 200,
TASKBAR_HEIGHT - 2*opt_bw, False);
if (count_tasks() <= MAX_CLIENTS_ON_TASKBAR) {
for (c = head_client; c; c = c->next) {
debug("loop3");
if (c->barname) sprintf(tasks_string, "%s", c->barname);
if (!tasks_string) {
debug("tasks_string is NULL in draw_tasks!\n");
exit(1);
}
if (offset + XTextWidth(font, tasks_string,
strlen(tasks_string)) +
2*SPACE < DisplayWidth(dpy, 0) - 200) {
if (c->minimized) {
XDrawString(dpy, taskbar,
hidden_string_gc,
offset + SPACE,
FONT_YOFF,
tasks_string,
strlen(tasks_string));
}
else if (tasks_string && c == focused_client) {
XDrawString(dpy, taskbar,
taskbar_focus_fg_gc,
offset + SPACE,
FONT_YOFF,
tasks_string,
strlen(tasks_string));
}
else {
XDrawString(dpy, taskbar,
normal_string_gc,
offset + SPACE,
FONT_YOFF,
tasks_string,
strlen(tasks_string));
}
XDrawRectangle(dpy, taskbar, border_gc,
offset,
SPACE,
XTextWidth(font, tasks_string,
strlen(tasks_string))
+ 2*SPACE, font->ascent +
font->descent + 2*SPACE);
c->left_offset = offset;
offset += XTextWidth(font, tasks_string,
strlen(tasks_string)) +
3*SPACE + 1;
c->right_offset = offset;
}
else {
break;
}
}
}
else {
XDrawString(dpy, taskbar, focus_string_gc,
offset + SPACE,
FONT_YOFF,
"Too many tasks to show on taskbar",
strlen("Too many tasks to show on taskbar"));
}
XSync(dpy, False);
}
int find_width(void) {
char *tasks_string = (char *) malloc(1024);
int offset = opt_bw + 1;
Client *c = (Client *) malloc (sizeof(Client));
for (c = head_client; c != NULL; c = c->next) {
debug("find width loop\n");
if (c->barname) {
sprintf(tasks_string, "%s", c->barname);
}
offset += XTextWidth(font, tasks_string,
strlen(tasks_string)) + 3*SPACE ;
}
return offset;
}
Client * find_client_with_longest_name() {
int longest_so_far = 0;
Client *c = (Client *) malloc (sizeof(Client));
Client *long_c = (Client *) malloc (sizeof(Client));
for (c = head_client; c; c = c->next) {
if (strlen(c->barname) > longest_so_far) {
long_c = c;
longest_so_far = strlen(c->barname);
}
}
return long_c;
}
void dec_barname(Client *c) {
if (!c) {
debug("c was NULL in dec_barname()\n");
exit(1);
}
if (strlen(c->barname) >= 4) {
c->barname[strlen(c->barname)-1] = '\0';
c->barname[strlen(c->barname)-1] = '.';
c->barname[strlen(c->barname)-2] = '.';
c->barname[strlen(c->barname)-3] = '.';
}
}
/* Do initial setup of the taskbar */
void start_taskbar(void) {
GC taskbar_gc;
XSetWindowAttributes p_attr;
p_attr.override_redirect = True;
p_attr.background_pixel = taskbar_bg.pixel;
p_attr.border_pixel = bd.pixel;
p_attr.backing_store = Always;
p_attr.event_mask = ChildMask | ButtonPressMask | ExposureMask
| CWBackingPixel | CWBackPixel | EnterWindowMask | KeyPressMask;
taskbar = XCreateWindow(dpy,
root,
0,
DisplayHeight(dpy, 0) - TASKBAR_HEIGHT - 2*opt_bw,
DisplayWidth(dpy, 0) - 4, //width
TASKBAR_HEIGHT,
opt_bw,
DefaultDepth(dpy, screen),
InputOutput,
CopyFromParent,
CWOverrideRedirect |CWBorderPixel|CWEventMask|
CWBackPixel|CWBackingStore, &p_attr);
XSelectInput(dpy, taskbar, ChildMask | ColormapChangeMask |
EnterWindowMask | LeaveWindowMask | PropertyChangeMask |
KeyPressMask| ButtonPressMask);
XMapWindow(dpy, taskbar);
taskbar_gc = XCreateGC(dpy, taskbar, 0, NULL);
XSync(dpy, False);
}
/* This function name is fucked up. Need to change it */
void taskbar_start(void) {
pid_t child_pid;
time_t mytime_t;
struct tm *mytm;
char *time_string = malloc(1024);
char *full_string = malloc(1024);
child_pid = fork();
if (child_pid == -1) {
debug("Unable to fork()!\n");
exit(1);
}
else if (child_pid == 0) {
/* We need a seperate Display to avoid race conditions */
child_dpy = XOpenDisplay(opt_display);
while (1) {
mytime_t = time(NULL);
mytm = localtime(&mytime_t);
strftime(time_string, 1024, STRFTIME_STRING,
mytm);
sprintf(full_string, "%s", //current_desk,
time_string);
draw_bartime(full_string);
sleep(60);
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1