Esempio n. 1
0
static LRESULT myWindowProc(HWND hWnd,	UINT Msg, WPARAM wParam, LPARAM lParam)
{
	HDC			dc;
	PAINTSTRUCT	ps;
	#if GINPUT_NEED_TOGGLE
		HBRUSH		hbrOn, hbrOff;
		HPEN		pen;
		RECT		rect;
		HGDIOBJ		old;
		POINT 		p;
		coord_t		pos;
		uint8_t		bit;
	#endif

	switch (Msg) {
	case WM_CREATE:
		break;
	case WM_LBUTTONDOWN:
		#if GINPUT_NEED_MOUSE
			if ((coord_t)HIWORD(lParam) < wHeight) {
				mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
				goto mousemove;
			}
		#endif
		#if GINPUT_NEED_TOGGLE
			bit = 1 << ((coord_t)LOWORD(lParam)*8/wWidth);
			toggles ^= bit;
			rect.left = 0;
			rect.right = wWidth;
			rect.top = wHeight;
			rect.bottom = wHeight + WIN32_BUTTON_AREA;
			InvalidateRect(hWnd, &rect, FALSE);
			UpdateWindow(hWnd);
			#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
				ginputToggleWakeup();
			#endif
		#endif
		break;
	case WM_LBUTTONUP:
		#if GINPUT_NEED_TOGGLE
			if ((toggles & 0xF0)) {
				toggles &= 0x0F;
				rect.left = 0;
				rect.right = wWidth;
				rect.top = wHeight;
				rect.bottom = wHeight + WIN32_BUTTON_AREA;
				InvalidateRect(hWnd, &rect, FALSE);
				UpdateWindow(hWnd);
				#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
					ginputToggleWakeup();
				#endif
			}
		#endif
		#if GINPUT_NEED_MOUSE
			if ((coord_t)HIWORD(lParam) < wHeight) {
				mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
				goto mousemove;
			}
		#endif
		break;
#if GINPUT_NEED_MOUSE
	case WM_MBUTTONDOWN:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
			goto mousemove;
		}
		break;
	case WM_MBUTTONUP:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
			goto mousemove;
		}
		break;
	case WM_RBUTTONDOWN:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
			goto mousemove;
		}
		break;
	case WM_RBUTTONUP:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
			goto mousemove;
		}
		break;
	case WM_MOUSEMOVE:
		if ((coord_t)HIWORD(lParam) >= wHeight)
			break;
	mousemove:
		mousex = (coord_t)LOWORD(lParam); 
		mousey = (coord_t)HIWORD(lParam); 
		#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
			ginputMouseWakeup();
		#endif
		break;
#endif
	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	case WM_SYSKEYUP:
	case WM_KEYUP:
		break;
	case WM_CHAR:
	case WM_DEADCHAR:
	case WM_SYSCHAR:
	case WM_SYSDEADCHAR:
		break;
	case WM_PAINT:
		dc = BeginPaint(hWnd, &ps);
		BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
			ps.rcPaint.right - ps.rcPaint.left,
			(ps.rcPaint.bottom > wHeight ? wHeight : ps.rcPaint.bottom) - ps.rcPaint.top,
			dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
		#if GINPUT_NEED_TOGGLE
			if (ps.rcPaint.bottom >= wHeight) {
				pen = CreatePen(PS_SOLID, 1, COLOR2BGR(Black));
				hbrOn = CreateSolidBrush(COLOR2BGR(Blue));
				hbrOff = CreateSolidBrush(COLOR2BGR(Gray));
				old = SelectObject(dc, pen);
				MoveToEx(dc, 0, wHeight, &p);
				LineTo(dc, wWidth, wHeight);
				for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
					rect.left = pos;
					rect.right = pos + wWidth/8;
					rect.top = wHeight;
					rect.bottom = wHeight + WIN32_BUTTON_AREA;
					FillRect(dc, &rect, (toggles & bit) ? hbrOn : hbrOff);
					if (pos > 0) {
						MoveToEx(dc, rect.left, rect.top, &p);
						LineTo(dc, rect.left, rect.bottom);
					}
				}
				DeleteObject(hbrOn);
				DeleteObject(hbrOff);
				SelectObject(dc, old);
			}
		#endif
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		SelectObject(dcBuffer, dcOldBitmap);
		DeleteDC(dcBuffer);
		DeleteObject(dcBitmap);
		winRootWindow = NULL;
		break;
	default:
		return DefWindowProc(hWnd, Msg, wParam, lParam);
	}
	return 0;
}
Esempio n. 2
0
static DECLARE_THREAD_FUNCTION(NetThread, param) {
	SOCKET_TYPE			listenfd, fdmax, i, clientfd;
	socklen_t			len;
	int					leni;
	fd_set				master, read_fds;
    struct sockaddr_in	addr;
    GDisplay *			g;
    netPriv *			priv;
	(void)param;

	// Start the sockets layer
	StartSockets();
	gfxSleepMilliseconds(100);					// Make sure the thread has time to start.

	/* clear the master and temp sets */
	FD_ZERO(&master);
	FD_ZERO(&read_fds);

	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == (SOCKET_TYPE)-1)
		gfxHalt("GDISP: uGFXnet - Socket failed");

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(GDISP_GFXNET_PORT);

	if (bind(listenfd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
		gfxHalt("GDISP: uGFXnet - Bind failed");

    if (listen(listenfd, 10) == -1)
		gfxHalt("GDISP: uGFXnet - Listen failed");


    /* add the listener to the master set */
    FD_SET(listenfd, &master);

    /* keep track of the biggest file descriptor */
    fdmax = listenfd; /* so far, it's this one*/

	#if GDISP_GFXNET_BROKEN_LWIP_ACCEPT
    {
		#warning "Using GDISP_GFXNET_BROKEN_LWIP_ACCEPT limits the number of displays and the use of GFXNET. Avoid if possible!"
		len = sizeof(addr);
		if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
			gfxHalt("GDISP: uGFXnet - Accept failed");

		// Look for a display that isn't connected
		for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
            // Ignore displays for other controllers
            #ifdef GDISP_DRIVER_LIST
                if (gvmt(g) != &GDISPVMT_uGFXnet)
                    continue;
            #endif
			if (!(g->flags & GDISP_FLG_CONNECTED))
				break;
		}

		// Was anything found?
		if (!g) {
			// No Just close the connection
			closesocket(clientfd);
			gfxHalt("GDISP: uGFXnet - Can't find display for connection");
			return 0;
		}

		// Save the descriptor
		FD_SET(clientfd, &master);
		if (clientfd > fdmax) fdmax = clientfd;
		priv = g->priv;
		memset(priv, 0, sizeof(netPriv));
		priv->netfd = clientfd;
		//printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1);

		// Send the initialisation data (2 words at a time)
		priv->data[0] = GNETCODE_INIT;
		priv->data[1] = GNETCODE_VERSION;
		sendpkt(priv->netfd, priv->data, 2);
		priv->data[0] = GDISP_SCREEN_WIDTH;
		priv->data[1] = GDISP_SCREEN_HEIGHT;
		sendpkt(priv->netfd, priv->data, 2);
		priv->data[0] = GDISP_LLD_PIXELFORMAT;
		priv->data[1] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0;
		MUTEX_ENTER;
		sendpkt(priv->netfd, priv->data, 2);
		MUTEX_EXIT;

		// The display is now working
		g->flags |= GDISP_FLG_CONNECTED;

		// Send a redraw all
		#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
			gdispGClear(g, gwinGetDefaultBgColor());
			gwinRedrawDisplay(g, FALSE);
		#endif
    }
	#endif

    /* loop */
    for(;;) {
		/* copy it */
		read_fds = master;
		if (select(fdmax+1, &read_fds, 0, 0, 0) == -1)
			gfxHalt("GDISP: uGFXnet - Select failed");

		// Run through the existing connections looking for data to be read
		for(i = 0; i <= fdmax; i++) {
			if(!FD_ISSET(i, &read_fds))
				continue;

			// Handle new connections
			if(i == listenfd) {
				len = sizeof(addr);
				if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
					gfxHalt("GDISP: uGFXnet - Accept failed");

                // Look for a display that isn't connected
                for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
                    // Ignore displays for other controllers
                    #ifdef GDISP_DRIVER_LIST
                        if (gvmt(g) != &GDISPVMT_uGFXnet)
                            continue;
                    #endif
                    if (!(g->flags & GDISP_FLG_CONNECTED))
                        break;
                }

				// Was anything found?
				if (!g) {
					// No Just close the connection
					closesocket(clientfd);
					//printf(New connection from %s on socket %d rejected as all displays are already connected\n", inet_ntoa(addr.sin_addr), clientfd);
					continue;
				}

				// Save the descriptor
				FD_SET(clientfd, &master);
				if (clientfd > fdmax) fdmax = clientfd;
				priv = g->priv;
				memset(priv, 0, sizeof(netPriv));
				priv->netfd = clientfd;
				//printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1);

				// Send the initialisation data (2 words at a time)
				priv->data[0] = GNETCODE_INIT;
				priv->data[1] = GNETCODE_VERSION;
				sendpkt(priv->netfd, priv->data, 2);
				priv->data[0] = GDISP_SCREEN_WIDTH;
				priv->data[1] = GDISP_SCREEN_HEIGHT;
				sendpkt(priv->netfd, priv->data, 2);
				priv->data[0] = GDISP_LLD_PIXELFORMAT;
				priv->data[1] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0;
				MUTEX_ENTER;
				sendpkt(priv->netfd, priv->data, 2);
				MUTEX_EXIT;

				// The display is now working
				g->flags |= GDISP_FLG_CONNECTED;

				// Send a redraw all
				#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
					gdispGClear(g, gwinGetDefaultBgColor());
					gwinRedrawDisplay(g, FALSE);
				#endif

				continue;
			}

			// Handle data from a client

			// Look for a display that is connected and the socket descriptor matches
            for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
                // Ignore displays for other controllers
                #ifdef GDISP_DRIVER_LIST
                    if (gvmt(g) != &GDISPVMT_uGFXnet)
                        continue;
                #endif
				priv = g->priv;
				if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == i)
					break;
            }
			if (!g)
				gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection");

			if ((g->flags & GDISP_FLG_HAVEDATA)) {
				// The higher level is still processing the previous data.
				//	Give it a chance to run by coming back to this data.
				gfxSleepMilliseconds(1);
				continue;
			}

			/* handle data from a client */
			MUTEX_ENTER;
			if ((leni = recv(i, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
				// Socket closed or in error state
				MUTEX_EXIT;
				g->flags &= ~GDISP_FLG_CONNECTED;
				memset(priv, 0, sizeof(netPriv));
				closesocket(i);
				FD_CLR(i, &master);
				continue;
			}
			MUTEX_EXIT;

			// Do we have a full reply yet
			priv->databytes += leni;
			if (priv->databytes < sizeof(priv->data))
				continue;
			priv->databytes = 0;

			// Convert network byte or to host byte order
			priv->data[0] = ntohs(priv->data[0]);
			priv->data[1] = ntohs(priv->data[1]);

			// Process the data received
			switch(priv->data[0]) {
			#if GINPUT_NEED_MOUSE
				case GNETCODE_MOUSE_X:		priv->mousex = priv->data[1];		break;
				case GNETCODE_MOUSE_Y:		priv->mousey = priv->data[1];		break;
				case GNETCODE_MOUSE_B:
					priv->mousebuttons = priv->data[1];
					// Treat the button event as the sync signal
					#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
						ginputMouseWakeup();
					#endif
					break;
			#endif
			case GNETCODE_CONTROL:
			case GNETCODE_READ:
				g->flags |= GDISP_FLG_HAVEDATA;
				break;
			case GNETCODE_KILL:
				gfxHalt("GDISP: uGFXnet - Display sent KILL command");
				break;

			default:
				// Just ignore unrecognised data
				break;
			}
		}
	}
    return 0;
}