Example #1
0
const char *TcpSocketErrorDesc(int code)
{
	static Tuple2<int, const char *> err[] = {
		{ WSAEINTR,                 "Interrupted function call." },
		{ WSAEACCES,                "Permission denied." },
		{ WSAEFAULT,                "Bad address." },
		{ WSAEINVAL,                "Invalid argument." },
		{ WSAEMFILE,                "Too many open files." },
		{ WSAEWOULDBLOCK,           "Resource temporarily unavailable." },
		{ WSAEINPROGRESS,           "Operation now in progress." },
		{ WSAEALREADY,              "Operation already in progress." },
		{ WSAENOTSOCK,              "TcpSocket operation on nonsocket." },
		{ WSAEDESTADDRREQ,          "Destination address required." },
		{ WSAEMSGSIZE,              "Message too long." },
		{ WSAEPROTOTYPE,            "Protocol wrong type for socket." },
		{ WSAENOPROTOOPT,           "Bad protocol option." },
		{ WSAEPROTONOSUPPORT,       "Protocol not supported." },
		{ WSAESOCKTNOSUPPORT,       "TcpSocket type not supported." },
		{ WSAEOPNOTSUPP,            "Operation not supported." },
		{ WSAEPFNOSUPPORT,          "Protocol family not supported." },
		{ WSAEAFNOSUPPORT,          "Address family not supported by protocol family." },
		{ WSAEADDRINUSE,            "Address already in use." },
		{ WSAEADDRNOTAVAIL,         "Cannot assign requested address." },
		{ WSAENETDOWN,              "Network is down." },
		{ WSAENETUNREACH,           "Network is unreachable." },
		{ WSAENETRESET,             "Network dropped connection on reset." },
		{ WSAECONNABORTED,          "Software caused connection abort." },
		{ WSAECONNRESET,            "Connection reset by peer." },
		{ WSAENOBUFS,               "No buffer space available." },
		{ WSAEISCONN,               "TcpSocket is already connected." },
		{ WSAENOTCONN,              "TcpSocket is not connected." },
		{ WSAESHUTDOWN,             "Cannot send after socket shutdown." },
		{ WSAETIMEDOUT,             "Connection timed out." },
		{ WSAECONNREFUSED,          "Connection refused." },
		{ WSAEHOSTDOWN,             "Host is down." },
		{ WSAEHOSTUNREACH,          "No route to host." },
		{ WSAEPROCLIM,              "Too many processes." },
		{ WSASYSNOTREADY,           "Network subsystem is unavailable." },
		{ WSAVERNOTSUPPORTED,       "Winsock.dll version out of range." },
		{ WSANOTINITIALISED,        "Successful WSAStartup not yet performed." },
		{ WSAEDISCON,               "Graceful shutdown in progress." },
		{ WSATYPE_NOT_FOUND,        "Class type not found." },
		{ WSAHOST_NOT_FOUND,        "Host not found." },
		{ WSATRY_AGAIN,             "Nonauthoritative host not found." },
		{ WSANO_RECOVERY,           "This is a nonrecoverable error." },
		{ WSANO_DATA,               "Valid name, no data record of requested type." },
		{ WSASYSCALLFAILURE,        "System call failure." },
	};
	const Tuple2<int, const char *> *x = FindTuple(err, __countof(err), code);
	return x ? x->b : "Unknown error code.";
}
Example #2
0
gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
	GuiLock __;
	GdkEventKey *key;
	bool pressed = false;
	bool  retval = true;
	Value value;
	Ctrl *p = GetTopCtrlFromId(user_data);
#ifdef LOG_EVENTS
	String ev = "?";
	Tuple2<int, const char *> *f = FindTuple(xEvent, __countof(xEvent), event->type);
	if(f)
		ev = f->b;
	LOG(rmsecs() << " FETCH EVENT " << ev << " ctrl: " << Name(p));
#endif

	switch(event->type) {
	case GDK_EXPOSE:
	case GDK_DAMAGE:
		if(p) {
#ifdef LOG_EVENTS
			TimeStop tm;
#endif
			p->fullrefresh = false;
			GdkEventExpose *e = (GdkEventExpose *)event;
			SystemDraw w(gdk_cairo_create(p->gdk()), p->gdk());
			painting = true;
			Rect r = RectC(e->area.x, e->area.y, e->area.width, e->area.height);
			w.SetInvalid(e->region);
			w.Clip(r);
			p->UpdateArea(w, r);
			w.End();
			cairo_destroy(w);
			if(p->top->dr)
				DrawDragRect(*p, *p->top->dr);
			painting = false;
#ifdef LOG_EVENTS
			LOG("* " << ev << " elapsed " << tm);
#endif
		}
		return true;
	case GDK_DELETE:
		break;
	case GDK_FOCUS_CHANGE:
		if(p) {
			if(((GdkEventFocus *)event)->in)
				gtk_im_context_focus_in(p->top->im_context);
			else
				gtk_im_context_focus_out(p->top->im_context);
			AddEvent(user_data, EVENT_NONE, value, event);
		}
		return false;
	case GDK_LEAVE_NOTIFY:
	case GDK_MOTION_NOTIFY:
		break;
	case GDK_BUTTON_PRESS:
		value = DoButtonEvent(event, true);
		if(IsNull(value))
			return false;
		break;
	case GDK_2BUTTON_PRESS:
		value = DoButtonEvent(event, true);
		if(IsNull(value))
			return false;
		break;
	case GDK_BUTTON_RELEASE:
		value = DoButtonEvent(event, false);
		if(IsNull(value))
			return false;
		break;
	case GDK_SCROLL: {
		GdkEventScroll *e = (GdkEventScroll *)event;
		value = findarg(e->direction, GDK_SCROLL_UP, GDK_SCROLL_LEFT) < 0 ? -120 : 120;
		break;
	}
	case GDK_KEY_PRESS:
		pressed = true;
	case GDK_KEY_RELEASE:
		key = (GdkEventKey *)event;
		value = (int) key->keyval;
		if(pressed) {
			p = GetTopCtrlFromId(user_data);
			if(p && gtk_im_context_filter_keypress(p->top->im_context, key))
				return true;
		}
		break;
	case GDK_CONFIGURE: {
		retval = false;
		GdkEventConfigure *e = (GdkEventConfigure *)event;
		value = RectC(e->x, e->y, e->width, e->height);
		LLOG("GDK_CONFIGURE " << value);
		break;
	}
	default:
		return false;
	}
	AddEvent(user_data, event->type, value, event);
	return retval;
}
Example #3
0
void TupleTutorial()
{
	/// . Tuples

	/// Template class `Tuple` allows combining 2-4 values with
	/// different types. These are principally similar to `std::tuple`, with some advantages.
	/// Unlike `std::tuple`, individual elements are directly accessible as member variables
	/// `a`..`d`, `Tuple` supports persistent storage patterns (`Serialize`, `Jsonize`, `Xmlize`), hash
	/// code (`GetHashValue`), conversion to `String` and Value conversions.
	
	/// To create a `Tuple` value, you can use the `MakeTuple` function.

	Tuple<int, String, String> x = MakeTuple(12, "hello", "world");

	/// Individual values are accessible as members `a` .. `d`:

	DUMP(x.a);
	DUMP(x.b);
	DUMP(x.c);
	
	/// Or using `Get`:
	
	DUMP(x.Get<1>());
	DUMP(x.Get<int>());
	
	/// As long as all individual types have conversion to `String` (`AsString`), the tuple also
	/// has such conversion and thus can e.g. be easily logged:

	DUMP(x);

	/// As long as individual types have defined `GetHashValue`, so does `Tuple`:

	DUMP(GetHashValue(x));

	/// As long as individual types have defined `operator==`, `Tuple` has defined `operator==`
	/// and `operator!=`:

	Tuple<int, String, String> y = x;
	DUMP(x == y);
	DUMP(x != y);
	y.a++;
	DUMP(x == y);
	DUMP(x != y);

	/// As long as all individual types have defined `SgnCompare`,
	/// Tuple has SgnCompare, Compare method and operators <, <=, >, >=:

	DUMP(x.Compare(y));
	DUMP(SgnCompare(x, y));
	DUMP(x < y);
	
	/// GetCount returns the width of `Tuple`:
	
	DUMP(x.GetCount());
	
	/// Elements that are directly convertible with `Value` can be 'Get'/'Set':
	
	for(int i = 0; i < x.GetCount(); i++)
		DUMP(x.Get(i));
	
	///
	
	x.Set(1, "Hi");
	DUMP(x);
	
	/// As long as all individual types are convertible with `Value`, you can convert Tuple to
	/// `ValueArray` and back:
	
	ValueArray va = x.GetArray();
	DUMP(va);

	va.Set(2, "Joe");
	x.SetArray(va);
	
	/// It is OK to assign `Tuple` to `Tuple` with different individual types, as long as types
	/// are directly convertible:
	
	Tuple<double, String, String> d = x;
	DUMP(d);
	
	/// Tie can be used to assign tuple to l-values:
	
	int i;
	String s1, s2;
	
	Tie(i, s1, s2) = x;
	
	DUMP(i);
	DUMP(s1);
	DUMP(s2);

	/// U++ Tuples are carefully designed as POD type, which allows POD arrays to be intialized
	/// with classic C style:
	
	static Tuple2<int, const char *> map[] = {
		{ 1, "one" },
		{ 2, "one" },
		{ 3, "one" },
	};
	

	/// Simple FindTuple template function is provided to search for tuple based on the first
	/// value (`a`) (linear O(n) search):
	
	DUMP(FindTuple(map, __countof(map), 3)->b);
	
	///
}
Example #4
0
void Ctrl::Proc()
{
#ifdef LOG_EVENTS
	String ev = "?";
	Tuple2<int, const char *> *f = FindTuple(xEvent, __countof(xEvent), CurrentEvent.type);
	if(f)
		ev = f->b;
	LOG(rmsecs() << " PROCESS EVENT " << Upp::Name(this) << " " << ev);
	ProcStop tm;
	tm.ev = ev;
#endif
	if(!IsOpen())
		return;
	Ptr<Ctrl> _this = this;
	bool pressed = false;
	int  kv;
	static int clicktime = msecs() - 100000;
	switch(CurrentEvent.type) {
	case GDK_MOTION_NOTIFY: {
		GtkMouseEvent(MOUSEMOVE, MOUSEMOVE, 0);
		break;
	}
	case GDK_BUTTON_PRESS:
		if(!HasWndFocus() && !popup)
			SetWndFocus();
		ClickActivateWnd();
		if(ignoremouseup) {
			KillRepeat();
			ignoreclick = false;
			ignoremouseup = false;
		}
		if(!ignoreclick)
			GtkButtonEvent(msecs(clicktime) < 250 ? DOUBLE : DOWN);
		clicktime = msecs();
		break;
/*	case GDK_2BUTTON_PRESS:
		if(!ignoreclick)
			GtkButtonEvent(DOUBLE);
		break;
*/	case GDK_BUTTON_RELEASE:
		if(ignoreclick)
			EndIgnore();
		else
			GtkButtonEvent(UP);
		break;
	case GDK_SCROLL: {
		GtkMouseEvent(MOUSEWHEEL, MOUSEWHEEL, CurrentEvent.value);
		break;
	}
	case GDK_KEY_PRESS:
		pressed = true;
	case GDK_KEY_RELEASE:
		kv = CurrentEvent.value;
		if(kv >= 0 && kv < 65536) {
			LLOG("keyval " << FormatIntHex(kv) << ' ' << (char)kv);
			if(kv >= 'a' && kv <= 'z')
				kv = kv - 'a' + 'A';
			static Tuple2<int, int> cv[] = {
				{ GDKEY(BackSpace), K_BACKSPACE },
				{ GDKEY(Tab), K_TAB },
				{ GDKEY(ISO_Left_Tab), K_TAB },
				{ GDKEY(Return), K_ENTER },
				{ GDKEY(Escape), K_ESCAPE },
				{ GDKEY(space), K_SPACE },
				{ GDKEY(Control_L), K_CTRL_KEY },
				{ GDKEY(Control_R), K_CTRL_KEY },
				{ GDKEY(Shift_L), K_SHIFT_KEY },
				{ GDKEY(Shift_R), K_SHIFT_KEY },
				{ GDKEY(Alt_L), K_ALT_KEY },
				{ GDKEY(Alt_R), K_ALT_KEY },

				{ GDKEY(KP_Space), K_SPACE },
				{ GDKEY(KP_Tab), K_TAB },
				{ GDKEY(KP_Enter), K_ENTER },
				{ GDKEY(KP_F1), K_F1 },
				{ GDKEY(KP_F2), K_F2 },
				{ GDKEY(KP_F3), K_F3 },
				{ GDKEY(KP_F4), K_F4 },
				{ GDKEY(KP_Home), K_HOME },
				{ GDKEY(KP_Left), K_LEFT },
				{ GDKEY(KP_Up), K_UP },
				{ GDKEY(KP_Right), K_RIGHT },
				{ GDKEY(KP_Down), K_DOWN },
				{ GDKEY(KP_Page_Up), K_PAGEUP },
				{ GDKEY(KP_Page_Down), K_PAGEDOWN },
				{ GDKEY(KP_End), K_END },
				{ GDKEY(KP_Begin), K_HOME },
				{ GDKEY(KP_Insert), K_INSERT },
				{ GDKEY(KP_Delete), K_DELETE },
			};
			Tuple2<int, int> *x = FindTuple(cv, __countof(cv), kv);
			if(x)
				kv = x->b;
			else
				kv += K_DELTA;
			if(GetShift() && kv != K_SHIFT_KEY)
				kv |= K_SHIFT;
			if(GetCtrl() && kv != K_CTRL_KEY)
				kv |= K_CTRL;
			if(GetAlt() && kv != K_ALT_KEY)
				kv |= K_ALT;
			LLOG(GetKeyDesc(kv) << ", pressed: " << pressed << ", count: " << CurrentEvent.count);
#ifdef GDK_WINDOWING_X11
			if(pressed)
				for(int i = 0; i < hotkey.GetCount(); i++) {
					if(hotkey[i] && keyhot[i] == (dword)kv) {
						hotkey[i]();
						return;
					}
				}
#endif
			DispatchKey(!pressed * K_KEYUP + kv, CurrentEvent.count);
		}
		break;
	case EVENT_TEXT: {
		WString h = CurrentEvent.value;
		for(int i = 0; i < h.GetCount(); i++) // TODO: Add compression
			DispatchKey(h[i], 1);
		break;
	}
	case GDK_DELETE: {
		TopWindow *w = dynamic_cast<TopWindow *>(this);
		if(w) {
			if(IsEnabled()) {
				IgnoreMouseUp();
				w->WhenClose();
			}
		}
		return;
	}
	case GDK_CONFIGURE: {
			Rect rect = CurrentEvent.value;
			if(GetRect() != rect)
				SetWndRect(rect);
		}
		break;
	default:
		return;
	}
	if(_this)
		_this->PostInput();
}