Exemplo n.º 1
0
*/	LRESULT CALLBACK REBOL_Window_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM xy)
/*
**		A Window_Proc() message handler. Simply translate Windows
**		messages into a generic form that REBOL processes.
**
***********************************************************************/
{
	REBGOB *gob;
	REBCNT flags = 1 << EVF_NO_REQ; // (because no device request field)
	REBCNT i;
	REBCNT mw_num_lines;  // mouse wheel lines setting
	// In order to trace resizing, we need these state variables. It is
	// assumed that we are not re-entrant during this operation. In Win32
	// resizing is a modal loop and prevents it being a problem.
	static LPARAM last_xy = 0;
	static REBINT mode = 0;

	gob = (REBGOB *)GetWindowLong(hwnd, GWL_USERDATA);

	// Not a REBOL window (or early creation):
	if (!gob || !IS_WINDOW(gob)) {
		switch(msg) {
			case WM_PAINT:
				Paint_Window(hwnd);
				break;
			case WM_CLOSE:
				DestroyWindow(hwnd);
				break;
			case WM_DESTROY:
				PostQuitMessage(0);
				break;
			default:
				// Default processing that we do not care about:
				return DefWindowProc(hwnd, msg, wParam, xy);
		}
		return 0;
	}

	// Handle message:
	switch(msg)
	{
		case WM_PAINT:
			Paint_Window(hwnd);
			break;

		case WM_MOUSEMOVE:
			Add_Event_XY(gob, EVT_MOVE, xy, flags);
			//if (!(WIN_FLAGS(wp) & WINDOW_TRACK_LEAVE))
			//	Track_Mouse_Leave(wp);
			break;

		case WM_SIZE:
			//Reb_Print("SIZE %d\n", mode);
			if (wParam == SIZE_MINIMIZED) {
				//Invalidate the size but not win buffer
				gob->old_size.x = 0;
				gob->old_size.y = 0;
				Add_Event_XY(gob, EVT_MINIMIZE, xy, flags);
			} else {
				gob->size.x = LOWORD(xy);
				gob->size.y = HIWORD(xy);
				last_xy = xy;
				if (mode) {
					//Resize and redraw the window buffer (when resize dragging)
					Resize_Window(gob, TRUE);
					mode = EVT_RESIZE;
					break;
				} else {
					//Resize only the window buffer (when win gob size changed by REBOL code or using min/max buttons)
					if (!Resize_Window(gob, FALSE)){
						//size has been changed programatically - return only 'resize event
						Add_Event_XY(gob, EVT_RESIZE, xy, flags);
						break;
					}
				}
				//Otherwise send combo of 'resize + maximize/restore events
				if (wParam == SIZE_MAXIMIZED) i = EVT_MAXIMIZE;
				else if (wParam == SIZE_RESTORED) i = EVT_RESTORE;
				else i = 0;
				Add_Event_XY(gob, EVT_RESIZE, xy, flags);
				if (i) Add_Event_XY(gob, i, xy, flags);
			}
			break;

		case WM_MOVE:
			// Minimize and maximize call this w/o mode set.
			gob->offset.x = LOWORD(xy);
			gob->offset.y = HIWORD(xy);
			last_xy = xy;
			if (mode) mode = EVT_OFFSET;
			else Add_Event_XY(gob, EVT_OFFSET, xy, flags);
			break;

		case WM_ENTERSIZEMOVE:
			mode = -1; // possible to ENTER and EXIT w/o SIZE change
			break;

		case WM_EXITSIZEMOVE:
			if (mode > 0) Add_Event_XY(gob, mode, last_xy, flags);
			mode = 0;
			break;

		case WM_MOUSELEAVE:
			// Get cursor position, not the one given in message:
			//GetCursorPos(&x_y);
			//ScreenToClient(hwnd, &x_y);
			//xy = (x_y.y << 16) + (x_y.x & 0xffff);
			Add_Event_XY(gob, EVT_MOVE, xy, flags);
			// WIN_FLAGS(wp) &= ~WINDOW_TRACK_LEAVE;
			break;

		case WM_MOUSEWHEEL:
			SystemParametersInfo(SPI_GETWHEELSCROLLLINES,0, &mw_num_lines, 0);
			if (LOWORD(wParam) == MK_CONTROL || mw_num_lines > WHEEL_DELTA) {
				Add_Event_XY(gob, EVT_SCROLL_PAGE, GET_WHEEL_DELTA_WPARAM(wParam), flags);
			} else {
				Add_Event_XY(gob, EVT_SCROLL_LINE, GET_WHEEL_DELTA_WPARAM(wParam) * mw_num_lines, flags);
			}
			break;

		case WM_TIMER:
			//Add_Event_XY(gob, EVT_TIME, xy, flags);
			break;

		case WM_SETCURSOR:
			if (LOWORD(xy) == 1) {
				SetCursor(Cursor);
				return TRUE;
			} else goto default_case;

		case WM_LBUTTONDBLCLK:
			SET_FLAG(flags, EVF_DOUBLE);
		case WM_LBUTTONDOWN:
			//if (!WIN_CAPTURED(wp)) {
			flags = Check_Modifiers(flags);
			Add_Event_XY(gob, EVT_DOWN, xy, flags);
			SetCapture(hwnd);
			//WIN_CAPTURED(wp) = EVT_BTN1_UP;
			break;

		case WM_LBUTTONUP:
			//if (WIN_CAPTURED(wp) == EVT_BTN1_UP) {
			flags = Check_Modifiers(flags);
			Add_Event_XY(gob, EVT_UP, xy, flags);
			ReleaseCapture();
			//WIN_CAPTURED(wp) = 0;
			break;

		case WM_RBUTTONDBLCLK:
			SET_FLAG(flags, EVF_DOUBLE);
		case WM_RBUTTONDOWN:
			//if (!WIN_CAPTURED(wp)) {
			flags = Check_Modifiers(flags);
			Add_Event_XY(gob, EVT_ALT_DOWN, xy, flags);
			SetCapture(hwnd);
			//WIN_CAPTURED(wp) = EVT_BTN2_UP;
			break;

		case WM_RBUTTONUP:
			//if (WIN_CAPTURED(wp) == EVT_BTN2_UP) {
			flags = Check_Modifiers(flags);
			Add_Event_XY(gob, EVT_ALT_UP, xy, flags);
			ReleaseCapture();
			//WIN_CAPTURED(wp) = 0;
			break;

		case WM_MBUTTONDBLCLK:
			SET_FLAG(flags, EVF_DOUBLE);
		case WM_MBUTTONDOWN:
			//if (!WIN_CAPTURED(wp)) {
			flags = Check_Modifiers(flags);
			Add_Event_XY(gob, EVT_AUX_DOWN, xy, flags);
			SetCapture(hwnd);
			break;

		case WM_MBUTTONUP:
			//if (WIN_CAPTURED(wp) == EVT_BTN2_UP) {
			flags = Check_Modifiers(flags);
			Add_Event_XY(gob, EVT_AUX_UP, xy, flags);
			ReleaseCapture();
			break;

		case WM_KEYDOWN:
			// Note: key repeat may cause multiple downs before an up.
		case WM_KEYUP:
			flags = Check_Modifiers(flags);
			for (i = 0; Key_To_Event[i] && wParam > Key_To_Event[i]; i += 2);
			if (wParam == Key_To_Event[i])
				Add_Event_Key(gob, (msg==WM_KEYDOWN) ? EVT_KEY : EVT_KEY_UP, Key_To_Event[i+1] << 16, flags);
			break;

		case WM_CHAR:
			flags = Check_Modifiers(flags);
			i = wParam & 0xff;
			//if (i == 127) i = 8; // Windows weirdness of converting ctrl-backspace to delete
			Add_Event_Key(gob, EVT_KEY, i, flags);
			break;

		case WM_DROPFILES:
			Add_File_Events(gob, flags, (HDROP)wParam);
			break;

		case WM_CLOSE:
			Add_Event_XY(gob, EVT_CLOSE, xy, flags);
			Close_Window(gob);	// Needs to be removed - should be done by REBOL event handling
//			DestroyWindow(hwnd);// This is done in Close_Window()
			break;

		case WM_DESTROY:
			PostQuitMessage(0);
			break;

		default:
		default_case:
			return DefWindowProc(hwnd, msg, wParam, xy);
	}
	return 0;
}
Exemplo n.º 2
0
void
mouseintr(uint tick)
{
	uint ch;
	ch = inb(0x64);
	if((ch & 0x01) == 0)
	{
		//cprintf("no data\n");
		state = 1;
		return;
	}

	acquire(&mouse_lock);
	ch = inb(0x60);

	if(state == 1)
	{
		if((ch & 0x08) == 0 || (ch & 0x04) != 0)
		{
			release(&mouse_lock);
			return;
		}
		left_down = (ch & 0x01) ? 1 : 0;
		right_down = (ch & 0x02) ? 1 : 0;
		x_sign = (ch & 0x10) ? 1 : 0;
		y_sign = (ch & 0x20) ? 1 : 0;
		x_overflow = (ch & 0x40) ? 1 : 0;
		y_overflow = (ch & 0x80) ? 1 : 0;
		state = 2;
		release(&mouse_lock);
		//cprintf("state1\n");
		//cprintf("overflow: %d\n", y_overflow);
		return;
	}
	else if(state == 2)
	{
		int dis;
		if(x_sign == 0)
			dis = ch;
		else
			dis = ch - 256;
		if(dis > 50 || dis < -50)
		{
			//cprintf("error");
			state = 1;
			release(&mouse_lock);
			return;
		}
		//cprintf("xdis: %d, sign: %d\n", dis, x_sign);
		x_position += dis;
		if(x_position < 0)
			x_position = 0;
		if(x_position > SCREEN_WIDTH - SIZE_X_MOUSE)
			x_position = SCREEN_WIDTH - SIZE_X_MOUSE;
		state = 3;
		release(&mouse_lock);
		//cprintf("state2\n");
		return;
	}
	else if(state == 3)
	{
		int dis;
		if(y_sign == 0)
			dis = ch;
		else
			dis = ch - 256;
		if(dis > 50 || dis < -50)
		{
			//cprintf("error");
			state = 1;
			release(&mouse_lock);
			return;
		}
		//cprintf("ydis: %d, sign: %d, overflow: %d\n", dis, y_sign, y_overflow);
		y_position -= dis;
		if(y_position < 0)
			y_position = 0;
		if(y_position > SCREEN_HEIGHT - SIZE_Y_MOUSE)
			y_position = SCREEN_HEIGHT - SIZE_Y_MOUSE;
		state = 1;
		release(&mouse_lock);
		//cprintf("state3\n");
	}
	else
	{
		state = 1;
		release(&mouse_lock);
		return;
	}

	event = 0;

	if(left_already_down == 0 && right_already_down == 0)
	{
		if(left_down == 1)
		{
			left_already_down = 1;
			x_drag_start = x_position;
			y_drag_start = y_position;
		}
		else if(right_down == 1)
		{
			right_already_down = 1;
		}
	}

	else if(left_already_down == 1)
	{
		if(left_down == 0)
		{
			//cprintf("dragging: %d\n", is_dragging);
			if(is_dragging == 1)
			{
				event = DRAG_RELEASE;
				is_dragging = 0;
			}
			else
			{
				int dtick = tick - left_click_tick;
				//cprintf("tick: %d\n", dtick);
				if(dtick > 15)
				{
					event = LEFT_CLICK;
					left_click_tick = tick;
				}
				else
				{
					event = DOUBLE_CLICK;
					left_click_tick = -20;
				}
			}
			left_already_down = 0;
		}
		else
		{
			event = DRAGGING;
			is_dragging = 1;
		}
	}

	else if(right_already_down == 1)
	{
		if(right_down == 0)
		{
			event = RIGHT_CLICK;
			right_already_down = 0;
		}
	}

	if(event == 0)
	{
		draw_mouse(x_position, y_position);
		return;
	}

	struct Window* win;
	int click_icon = -1;
	if(y_position > ICON_Y && y_position < ICON_Y + 75 + 18)
	{
		if(event != LEFT_CLICK)
		{
			draw_mouse(x_position, y_position);
			return;
		}
		if(x_position > ICON_X1 && x_position < ICON_X1 + 75)
		{
			click_icon = ICON_FINDER;
		}
		else if(x_position > ICON_X2 && x_position < ICON_X2 + 75)
		{
			click_icon = ICON_PHOTO;
		}
		else if(x_position > ICON_X3 && x_position < ICON_X3 + 75)
		{
			click_icon = ICON_TEXT;
		}
		else if(x_position > ICON_X4 && x_position < ICON_X4 + 75)
		{
			click_icon = ICON_GAME;
		}
		else if(x_position > ICON_X5 && x_position < ICON_X5 + 75)
		{
			click_icon = ICON_DRAW;
		}
		else if(x_position > ICON_X6 && x_position < ICON_X6 + 75)
		{
			click_icon = ICON_SETTING;
		}
		else
		{
			draw_mouse(x_position, y_position);
			return;
		}

		win = get_window_by_icon(click_icon);
		if(click_icon == ICON_FINDER || win == 0)
		{
			win = Add_Window(click_icon);
			if(win != 0)
				draw_window(win);
		}
		else if(win != 0 && WindowLine->next != win)
		{
			draw_window(win);
			Focus(win);
		}
  		display_to_screen(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
		draw_mouse(x_position, y_position);
		return;
	}

	win = Click_Get_Window(x_position, y_position);
	if(win != 0 && WindowLine->next != win)
	{
		//cprintf("window: %d\n", win->Cur_icon);
		if(event == LEFT_CLICK)
		{
			draw_window(win);
	  		display_to_screen(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
			Focus(win);
		}
	}
	else if(win != 0)
	{
		int Pos_x, Pos_y;
		Pos_x = x_position - win->Pos_x;
		Pos_y = y_position - win->Pos_y;
		if(Pos_x > 2 && Pos_x < 18 && Pos_y > 2 && Pos_y < 18)
		{
			Close_Window();
			draw_again(get_current_bg());
		}
		else if(Pos_y < 20)
		{
			if(event == DRAGGING)
			{
				if(dragging_top_window == 0)
				{
					dragging_top_window = 1;
					x_drag_window = win->Pos_x;
					y_drag_window = win->Pos_y;
					dragging_count = 0;
				}
				dragging_count = (dragging_count + 1) % 5;
				if(dragging_count != 0)
					return;
				if(x_drag_window + (x_position - x_drag_start) < 0 || 
					x_drag_window + (x_position - x_drag_start) + WindowWidth > SCREEN_WIDTH ||
					y_drag_window + (y_position - y_drag_start) < 0 ||
					y_drag_window + (y_position - y_drag_start) + WindowHeight > SCREEN_HEIGHT)
					return;
				draw_bottom(get_current_bg());
				win->Pos_x = x_drag_window + (x_position - x_drag_start);
				win->Pos_y = y_drag_window + (y_position - y_drag_start);
				draw_window(win);
				display_to_screen(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
			}
			else if(event == DRAG_RELEASE)
			{
				if(dragging_top_window == 1)
					dragging_top_window = 0;
			}
		}
		else if(Pos_y > 20 && Pos_y < WindowHeight - 20)
		{
			switch(win->Cur_icon)
			{
				case ICON_DRAW:
					draw(win, Pos_x, Pos_y, event);
					break;
				case ICON_SETTING:
					setting(Pos_x, Pos_y, event);
					break;
				case ICON_FINDER:
					Folder(win, Pos_x, Pos_y, event);
					break;
				case ICON_GAME:
					pointInGameWindow(Pos_x, Pos_y, event);
					break;
				case 8://LIST_FINDER
					Folder(win, Pos_x, Pos_y, event);
					break;
				case 9://LAYOUT_FINDER
					Folder(win, Pos_x, Pos_y, event);
					break;
			}
		}
	}

	draw_mouse(x_position, y_position);


}