Ejemplo n.º 1
0
/*
 * The user must be able to call AnimationStart and AnimationStop when this thread is being executed.
 */
void AnimationQueue() {
	struct LinkedList* _List = NULL;
	struct LnkLst_Node* _Itr = NULL;
	struct Animation* _Animation = NULL;
	int _Time = SDL_GetTicks();

	while(_Itr != NULL) {
		_Animation = (struct Animation*) _Itr->Data;
		if(_Time - _Animation->LastFramePlay >= _Animation->Base->Frames[_Animation->CurrFrame].Speed) {
			AnimationNextFrame(_Animation, _Time);
		}
		_Itr = _Itr->Next;
	}
	_Itr = _List->Front;
	if(_List->Size == 0)
		return;
	SDL_LockMutex(g_AnimationLock);
		do {
			_Animation = (struct Animation*) _Itr->Data;
			DestroyAnimation(_Animation);
			LnkLstRemove(_List, _Itr);
			_Itr = _Itr->Next;
		} while(_Itr != NULL);
	SDL_UnlockMutex(g_AnimationLock);
}
ANIMATION* CreateAnimationFromGIF89a (HDC hdc, MG_RWops* area)
{
    unsigned char c;
    int ok = 0;
    MYBITMAP mybmp;
    GIFSCREEN GifScreen;
    IMAGEDESC ImageDesc;

    ANIMATION* anim;
    ANIMATIONFRAME* frame, *current = NULL;
    
    anim = calloc (1, sizeof (ANIMATION));
    if (anim == NULL)
        return NULL;

    anim->time_unit = 1;

    if (ReadGIFGlobal (area, &GifScreen) < 0)
        goto error;

    anim->width = GifScreen.Width;
    anim->height = GifScreen.Height;
    if (GifScreen.Background >= 0) {
        anim->bk = GifScreen.ColorMap [GifScreen.Background];
        anim->bk.a = 1;
    }
    else {
        anim->bk.r = anim->bk.g = anim->bk.b = 255;
        anim->bk.a = 0;
    }

    _MG_PRINTF ("EX_CTRL>GIF89a: Background: %d, %d, %d.\n",
                anim->bk.r, anim->bk.g, anim->bk.b);

    if ((ok = ReadOK (area, &c, 1)) == 0) {
        _MG_PRINTF ("EX_CTRL>GIF89a: EOF on image data\n");
        goto error;
    }

    while (c != ';' && ok > 0) {
        switch (c) {
        case '!':
            if ( (ok = ReadOK (area, &c, 1)) == 0) {
                _MG_PRINTF ("EX_CTRL>GIF89a: EOF on image data\n");
                goto error;
            }
            DoExtension (area, c, &GifScreen);
            _MG_PRINTF ("EX_CTRL>GIF89a: Extension info: %d, %d, %d, %d, %d, %d\n",
                        GifScreen.Width, GifScreen.Height, 
                        GifScreen.AspectRatio, GifScreen.delayTime,
                        GifScreen.disposal, GifScreen.transparent);
            break;

        case ',':
            if (ReadImageDesc (area, &ImageDesc, &GifScreen) < 0) {
                goto error;
            }
            else {
                if (ReadImage (area, &mybmp, &ImageDesc, &GifScreen, 0) < 0)
                    goto error;
            }
            _MG_PRINTF ("EX_CTRL>GIF89a: Image Descriptor: %d, %d, %d, %d, %d\n",
                        ImageDesc.Top, ImageDesc.Left,
                        ImageDesc.Width, ImageDesc.Height,
                        ImageDesc.haveColorMap);

            frame = (ANIMATIONFRAME*) calloc (1, sizeof (ANIMATIONFRAME));
            if (!frame)
                goto error;
            else {
                frame->next = NULL;
                frame->disposal = GifScreen.disposal;
                frame->off_y = ImageDesc.Left;
                frame->off_x = ImageDesc.Top;
                frame->width = mybmp.w;
                frame->height = mybmp.h;
                frame->delay_time = (GifScreen.delayTime>10)?GifScreen.delayTime:10;
                _MG_PRINTF ("EX_CTRL>GIF89a: frame info: %d, %d, %d, %d\n", 
                        frame->off_x, frame->off_y, frame->delay_time, 
                        GifScreen.transparent);

                if ((frame->mem_dc = CreateMemDCFromMyBitmap (&mybmp, ImageDesc.ColorMap)) == 0) {
                    free (mybmp.bits);
                    free (frame);
                    _MG_PRINTF ("EX_CTRL>GIF89a: Error when expand frame bitmap.\n");
                    goto error;
                }
                frame->bits = mybmp.bits;
                
                if (anim->frames == NULL) {
                    anim->frames = frame;
                    current = frame;
                    current->prev = NULL;
                }
                else {
                    frame->prev = current;
                    current->next = frame;
                    current = current->next;
                }

                anim->nr_frames++ ;
            }
            break;
        }

        ok = ReadOK (area, &c, 1);
    }

    return anim;

error:
    DestroyAnimation (anim, TRUE);
    return NULL;
}
Ejemplo n.º 3
0
static LRESULT CALLBACK ACCWndProc(HWND hwnd, UINT msg,  WPARAM wParam, LPARAM lParam) {
	ACCData* data =  (ACCData *) GetWindowLongPtr(hwnd, 0);
	switch(msg)
	{
		case WM_NCCREATE:
		{
			SetWindowLongPtr(hwnd, GWL_STYLE, GetWindowLongPtr(hwnd, GWL_STYLE) | BS_OWNERDRAW);
			SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT);

			data = (ACCData*) mir_alloc(sizeof(ACCData));
			if (data == NULL)
				return FALSE;
			SetWindowLongPtr(hwnd, 0, (LONG_PTR)data);

			ZeroMemory(data, sizeof(ACCData));
			data->hHook = HookEventMessage(ME_AV_AVATARCHANGED, hwnd, DM_AVATARCHANGED);
			data->hHookMy = HookEventMessage(ME_AV_MYAVATARCHANGED, hwnd, DM_MYAVATARCHANGED);
			data->hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
			data->borderColor = -1;
			data->bkgColor = -1;
			data->avatarBorderColor = -1;
			data->respectHidden = TRUE;
			data->showingFlash = FALSE;
			data->resizeIfSmaller = TRUE;
			data->showingAnimatedGif = FALSE;
			data->fAero = FALSE;

			return TRUE;
		}
		case WM_NCDESTROY:
		{
			DestroyAnimation(hwnd, data);
			if (data)
			{
				UnhookEvent(data->hHook);
				UnhookEvent(data->hHookMy);
				mir_free(data);
			}
			SetWindowLongPtr(hwnd, 0, (LONG_PTR)NULL);
			break;
		}
		case WM_SETFONT:
		{
			data->hFont = (HFONT)wParam;
			Invalidate(hwnd);
			break;
		}
		case AVATAR_SETCONTACT:
		{
			DestroyAnimation(hwnd, data);

			data->hContact = lParam;
			if (lParam == NULL)
				data->proto[0] = '\0';
			else
				lstrcpynA(data->proto, GetContactProto(data->hContact), sizeof(data->proto));

			StartAnimation(hwnd, data);

			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETPROTOCOL:
		{
			DestroyAnimation(hwnd, data);

			data->hContact = NULL;
			if (lParam == NULL)
				data->proto[0] = '\0';
			else
				lstrcpynA(data->proto, (char *) lParam, sizeof(data->proto));

			StartAnimation(hwnd, data);

			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETBKGCOLOR:
		{
			data->bkgColor = (COLORREF) lParam;
			if (data->showingFlash)
				SetBkgFlash(hwnd, data);
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETBORDERCOLOR:
		{
			data->borderColor = (COLORREF) lParam;
			if (data->showingFlash)
				ResizeFlash(hwnd, data);
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETAVATARBORDERCOLOR:
		{
			data->avatarBorderColor = (COLORREF) lParam;
			if (data->showingFlash)
				ResizeFlash(hwnd, data);
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETAVATARROUNDCORNERRADIUS:
		{
			data->avatarRoundCornerRadius = (int) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETNOAVATARTEXT:
		{
			lstrcpyn(data->noAvatarText, TranslateTS((TCHAR*) lParam), SIZEOF(data->noAvatarText));
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_RESPECTHIDDEN:
		{
			data->respectHidden = (BOOL) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}
		case AVATAR_SETRESIZEIFSMALLER:
		{
			data->resizeIfSmaller = (BOOL) lParam;
			NotifyAvatarChange(hwnd);
			Invalidate(hwnd);
			return TRUE;
		}

		case AVATAR_SETAEROCOMPATDRAWING:
			data->fAero = lParam;
			return(TRUE);

		case AVATAR_GETUSEDSPACE:
		{
			int *width = (int *)wParam;
			int *height = (int *)lParam;

			RECT rc;
			GetClientRect(hwnd, &rc);

			// Get avatar
			if (data->showingFlash && ServiceExists(MS_FAVATAR_GETINFO))
			{
				FLASHAVATAR fa = {0};
				fa.hContact = data->hContact;
				fa.cProto = data->proto;
				fa.hParentWindow = hwnd;
				fa.id = 1675;
				CallService(MS_FAVATAR_GETINFO, (WPARAM)&fa, 0);
				if (fa.hWindow != NULL)
				{
					*width = rc.right - rc.left;
					*height = rc.bottom - rc.top;
					return TRUE;
				}
			}

			avatarCacheEntry *ace;
			if (data->hContact == NULL)
				ace = (avatarCacheEntry *) CallService(MS_AV_GETMYAVATAR, 0, (LPARAM) data->proto);
			else
				ace = (avatarCacheEntry *) CallService(MS_AV_GETAVATARBITMAP, (WPARAM) data->hContact, 0);

			if (ace == NULL || ace->bmHeight == 0 || ace->bmWidth == 0
				|| (data->respectHidden && (ace->dwFlags & AVS_HIDEONCLIST)))
			{
				*width = 0;
				*height = 0;
				return TRUE;
			}

			// Get its size
			int targetWidth = rc.right - rc.left;
			int targetHeight = rc.bottom - rc.top;

			if (!data->resizeIfSmaller && ace->bmHeight <= targetHeight && ace->bmWidth <= targetWidth)
			{
				*height = ace->bmHeight;
				*width = ace->bmWidth;
			}
			else if (ace->bmHeight > ace->bmWidth)
			{
				float dScale = targetHeight / (float)ace->bmHeight;
				*height = targetHeight;
				*width = (int) (ace->bmWidth * dScale);
			}
			else
			{
				float dScale = targetWidth / (float)ace->bmWidth;
				*height = (int) (ace->bmHeight * dScale);
				*width = targetWidth;
			}

			return TRUE;
		}
		case DM_AVATARCHANGED:
		{
			if (data->hContact == wParam)
			{
				DestroyAnimation(hwnd, data);
				StartAnimation(hwnd, data);

				NotifyAvatarChange(hwnd);
				Invalidate(hwnd);
			}
			break;
		}
		case DM_MYAVATARCHANGED:
		{
			if (data->hContact == NULL && strcmp(data->proto, (char*) wParam) == 0)
			{
				DestroyAnimation(hwnd, data);
				StartAnimation(hwnd, data);

				NotifyAvatarChange(hwnd);
				Invalidate(hwnd);
			}
			break;
		}
		case WM_NCPAINT:
		case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);
			if (hdc == NULL)
				break;

			int oldBkMode = SetBkMode(hdc, TRANSPARENT);
			SetStretchBltMode(hdc, HALFTONE);

			RECT rc;
			GetClientRect(hwnd, &rc);

			// Draw background
			if (data->bkgColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->bkgColor);
				FillRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			if (data->hContact == NULL && data->proto[0] == '\0'
				&& db_get_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1))
			{
				DrawText(hdc, data->hFont, rc, TranslateT("Protocols have different avatars"));
			}

			// Has a flash avatar
			else if (data->showingFlash)
			{
				// Don't draw

				// Draw control border if needed
				if (data->borderColor == -1 && data->avatarBorderColor != -1)
				{
					HBRUSH hbrush = CreateSolidBrush(data->avatarBorderColor);
					FrameRect(hdc, &rc, hbrush);
					DeleteObject(hbrush);
				}
			}

			// Has an animated gif
			// Has a "normal" image
			else
			{
				// Draw avatar
				AVATARDRAWREQUEST avdrq = {0};
				avdrq.cbSize = sizeof(avdrq);
				avdrq.rcDraw = rc;
				avdrq.hContact = data->hContact;
				avdrq.szProto = data->proto;
				avdrq.hTargetDC = hdc;
				avdrq.dwFlags = AVDRQ_HIDEBORDERONTRANSPARENCY
					| (data->respectHidden ? AVDRQ_RESPECTHIDDEN : 0)
					| (data->hContact != NULL ? 0 : AVDRQ_OWNPIC)
					| (data->avatarBorderColor == -1 ? 0 : AVDRQ_DRAWBORDER)
					| (data->avatarRoundCornerRadius <= 0 ? 0 : AVDRQ_ROUNDEDCORNER)
					| (data->fAero ? AVDRQ_AERO : 0)
					| (data->resizeIfSmaller ? 0 : AVDRQ_DONTRESIZEIFSMALLER);
				avdrq.clrBorder = data->avatarBorderColor;
				avdrq.radius = data->avatarRoundCornerRadius;

				INT_PTR ret;
				if (data->showingAnimatedGif)
				{
					InternalDrawAvatar(&avdrq, data->ag.hbms[data->ag.frame.num], data->ag.logicalWidth, data->ag.logicalHeight, 0);
					ret = 1;

					if (!data->ag.started)
					{
						SetTimer(hwnd, 0, data->ag.times[data->ag.frame.num], NULL);
						data->ag.started = TRUE;
					}
				}
				else
					ret = DrawAvatarPicture(0, (LPARAM)&avdrq);

				if (ret == 0)
					DrawText(hdc, data->hFont, rc, data->noAvatarText);
			}

			// Draw control border
			if (data->borderColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->borderColor);
				FrameRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			SetBkMode(hdc, oldBkMode);

			EndPaint(hwnd, &ps);
			return TRUE;
		}
		case WM_ERASEBKGND:
		{
			HDC hdc = (HDC) wParam;
			RECT rc;
			GetClientRect(hwnd, &rc);

			// Draw background
			if (data->bkgColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->bkgColor);
				FillRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			// Draw control border
			if (data->borderColor != -1)
			{
				HBRUSH hbrush = CreateSolidBrush(data->borderColor);
				FrameRect(hdc, &rc, hbrush);
				DeleteObject(hbrush);
			}

			return TRUE;
		}
		case WM_SIZE:
		{
			if (data->showingFlash)
				ResizeFlash(hwnd, data);
			InvalidateRect(hwnd, NULL, TRUE);
			break;
		}
		case WM_TIMER:
		{
			if (wParam != 0)
				break;
			KillTimer(hwnd, 0);

			if (!data->showingAnimatedGif)
				break;

			AnimatedGifDispodeFrame(data);

			int frame = data->ag.frame.num + 1;
			if (frame >= data->ag.frameCount)
			{
				// Don't need fi data no more
				AnimatedGifDeleteTmpValues(data);
				frame = 0;
			}
			AnimatedGifMountFrame(data, frame);

			data->ag.started = FALSE;
			InvalidateRect(hwnd, NULL, FALSE);

			break;
		}
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}
Ejemplo n.º 4
0
void DestroyVisual(Visual *& visual){
		DestroyAnimation(visual->animation);
		SafeDelete(visual->rect);
		SafeDelete(visual);
}