summaryrefslogtreecommitdiff
path: root/window_timeout/list.c
blob: 1ba076e4d5240a31ca7dfe07567e8093a0df41ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "windowtimeout.h"

#define BASE_TIMER_ID		10000

struct Entry *list_head = 0;

BOOL me_typing;

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);

struct Entry *get_entry(HANDLE hContact) {
	struct Entry *current = list_head;
	while(current) {
		if(current->hContact == hContact)
			return current;
		current = current->next;
	}
	return 0;
}

struct Entry *get_entry_for_timer(UINT timer_id) {
	struct Entry *current = list_head;
	char buff[128];
	sprintf(buff, "get_entry_for_timerid. timer_id = %d", timer_id);
	msg(buff);
	while(current) {
		sprintf(buff, "checking entry with timer_id %d", current->timer_id);
		msg(buff);
		if(current->timer_id == timer_id)
			return current;
		current = current->next;
	}
	return 0;
}

void add_entry(HANDLE hContact) {
	struct Entry *entry = get_entry(hContact);
	if(!entry) {
		char buff[128];
		entry = mir_alloc(sizeof(struct Entry));

		sprintf(buff, "added entry. hcontact = %d", hContact);
		msg(buff);
		
		entry->hContact = hContact;
		entry->hwnd = 0;

		entry->next = list_head;
		entry->prev = 0;
		if(list_head) list_head->prev = entry;
		list_head = entry;

		entry->timer_id = 0;
		entry->typing = FALSE;
	}
}

void set_window_handle(HANDLE hContact, HWND hwnd) {
	struct Entry *entry = get_entry(hContact);
	if(entry) {
		msg("set window handle");
		entry->hwnd = hwnd;
	}
}

void set_typing(BOOL typing) {
	me_typing = typing;
}

void remove_entry(HANDLE hContact) {
	struct Entry *entry = get_entry(hContact);
	if(entry) {
		msg("remove entry");
		if(entry->prev) entry->prev->next = entry->next;
		if(entry->next) entry->next->prev = entry->prev;

		if(list_head == entry) list_head = list_head->next;

		KillTimer(0, entry->timer_id);

		mir_free(entry);
	}
}

void reset_timer(HANDLE hContact) {
	struct Entry *entry = get_entry(hContact);
	if(entry) {
		msg("reset timer");
		if(entry->timer_id) KillTimer(0, entry->timer_id);
		entry->timer_id = SetTimer(0, 0, options.timeout * 1000, TimerProc);
	}
}

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) {
	struct Entry *entry;
	char buff[128];

	KillTimer(0, idEvent);
	entry = get_entry_for_timer(idEvent);

	sprintf(buff, "timer. id = %d", idEvent);
	msg(buff);
	if(entry && entry->hwnd != 0) {
		if(me_typing) {
			entry->timer_id = SetTimer(0, 0, TYPING_CHECK_DELAY, TimerProc);
		} else {
			msg("timer: close window");
			SendMessage(entry->hwnd, WM_CLOSE, 0, 0);
			remove_entry(entry->hContact);
		}
	}
}