summaryrefslogtreecommitdiff
path: root/protocols/Steam/src/steam_xstatus.cpp
blob: ca20df452a5ada8e0ec77b9fb32236b13a8cb334 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "common.h"

#define STATUS_TITLE_MAX 64
#define STATUS_DESC_MAX  250

static std::vector<int> xstatusIconsValid;
static std::map<int, int> xstatusIcons;

int OnReloadIcons(WPARAM wParam, LPARAM lParam)
{
	xstatusIconsValid.clear();
	return 0;
}

int CSteamProto::GetContactXStatus(MCONTACT hContact)
{
	return getDword(hContact, "XStatusId", 0) ? 1 : 0;
}

void SetContactExtraIcon(MCONTACT hContact, int status)
{
	char iconName[100];
	mir_snprintf(iconName, SIZEOF(iconName), "%s_%s", MODULE, "gaming");

	ExtraIcon_SetIcon(hExtraXStatus, hContact, (status > 0) ? Skin_GetIconHandle(iconName) : NULL);
}

INT_PTR CSteamProto::OnGetXStatusEx(WPARAM wParam, LPARAM lParam)
{
	MCONTACT hContact = (MCONTACT)wParam;

	CUSTOM_STATUS *pData = (CUSTOM_STATUS*)lParam;
	if (pData->cbSize < sizeof(CUSTOM_STATUS))
		return 1;

	// fill status member
	if (pData->flags & CSSF_MASK_STATUS)
		*pData->status = GetContactXStatus(hContact);

	// fill status name member
	if (pData->flags & CSSF_MASK_NAME)
	{
		int status = (pData->wParam == NULL) ? GetContactXStatus(hContact) : *pData->wParam;
		if (status < 1)
			return 1;

		ptrT title;
		if (pData->flags & CSSF_DEFAULT_NAME)
			title = mir_tstrdup(TranslateT("Playing"));
		else
			title = getTStringA(hContact, "XStatusName");

		if (pData->flags & CSSF_UNICODE)
			mir_tstrncpy(pData->ptszName, title, STATUS_TITLE_MAX);
		else
			mir_strncpy(pData->pszName, _T2A(title), STATUS_TITLE_MAX);
	}

	// fill status message member
	if (pData->flags & CSSF_MASK_MESSAGE) {
		ptrT message(getTStringA(hContact, "XStatusMsg"));
		
		if (pData->flags & CSSF_UNICODE)
			mir_tstrncpy(pData->ptszMessage, message, STATUS_DESC_MAX);
		else
			mir_strncpy(pData->pszMessage, _T2A(message), STATUS_DESC_MAX);
	}

	// disable menu
	if (pData->flags & CSSF_DISABLE_MENU)
		if (pData->wParam)
			*pData->wParam = true;

	// disable ui
	if (pData->flags & CSSF_DISABLE_UI)
		if (pData->wParam)
			*pData->wParam = true;

	// number of xstatuses
	if (pData->flags & CSSF_STATUSES_COUNT)
		if (pData->wParam)
			*pData->wParam = 1; // TODO: how to solve unknown count of games?

	// data sizes
	if (pData->flags & CSSF_STR_SIZES) {
		if (pData->wParam) *pData->wParam = STATUS_TITLE_MAX;
		if (pData->lParam) *pData->lParam = STATUS_DESC_MAX;
	}

	return 0;
}

HICON CSteamProto::GetXStatusIcon(int status, UINT flags)
{
	if (status < 1)
		return 0;

	char iconName[100];
	mir_snprintf(iconName, SIZEOF(iconName), "%s_%s", MODULE, "gaming");

	HICON icon = Skin_GetIcon(iconName, (flags & LR_BIGICON) ? 32 : 16);
	return (flags & LR_SHARED) ? icon : CopyIcon(icon);
}

INT_PTR CSteamProto::OnGetXStatusIcon(WPARAM wParam, LPARAM lParam)
{
	if (!wParam)
		wParam = GetContactXStatus(NULL);

	if (wParam < 1)
		return 0;

	return (INT_PTR)GetXStatusIcon(wParam, lParam);
}

INT_PTR CSteamProto::OnRequestAdvStatusIconIdx(WPARAM wParam, LPARAM lParam)
{
	int status = GetContactXStatus(wParam);
	if (status)
	{
		if (std::find(xstatusIconsValid.begin(), xstatusIconsValid.end(), status) == xstatusIconsValid.end())
		{
			// adding/updating icon
			HIMAGELIST clistImageList = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
			if (clistImageList)
			{
				HICON hXStatusIcon = GetXStatusIcon(status, LR_SHARED);

				std::map<int, int>::iterator it = xstatusIcons.find(status);
				if (it != xstatusIcons.end() && it->second > 0)
					ImageList_ReplaceIcon(clistImageList, it->first, hXStatusIcon);
				else
					xstatusIcons.insert(std::make_pair(status, ImageList_AddIcon(clistImageList, hXStatusIcon)));

				// mark icon index in the array as valid
				xstatusIconsValid.push_back(status);

				Skin_ReleaseIcon(hXStatusIcon);
			}
		}

		if (std::find(xstatusIconsValid.begin(), xstatusIconsValid.end(), status) != xstatusIconsValid.end())
		{
			std::map<int, int>::iterator it = xstatusIcons.find(status);
			if (it != xstatusIcons.end())
				return ((INT_PTR) it->second & 0xFFFF) << 16;
		}
	}

	return -1;
}