Extracting parts of the formatting method into configuration and an options helper...
[cslatevm.git] / src / plugins / x-windows.c
blobd8282a7258d8ae8eba9fbb2c0bb8b757ab39b625
4 #ifdef WIN32
5 # define EXPORT __declspec(dllexport)
6 #else
7 # define EXPORT
8 #endif
10 #include <X11/Xlib.h>
11 #include <X11/Xutil.h>
12 #include <X11/Xatom.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <cairo.h>
18 #include <cairo-xlib.h>
19 #include <stdint.h>
20 #include <inttypes.h>
23 typedef intptr_t slate_int_t;
26 union float_int_union {
28 slate_int_t i;
29 float f;
33 int main(void) {
34 Display *d;
35 Window w;
36 XEvent e;
37 char *msg = "Hello, World!";
38 int s;
40 /* open connection with the server */
41 d = XOpenDisplay(NULL);
42 if (d == NULL) {
43 fprintf(stderr, "Cannot open display\n");
44 exit(1);
47 s = DefaultScreen(d);
49 /* create window */
50 w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
51 BlackPixel(d, s), WhitePixel(d, s));
53 /* select kind of events we are interested in */
54 XSelectInput(d, w, ExposureMask | KeyPressMask);
56 /* map (show) the window */
57 XMapWindow(d, w);
59 /* event loop */
60 while (1) {
61 XNextEvent(d, &e);
62 /* draw or redraw the window */
63 if (e.type == Expose) {
64 XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
65 XDrawString(d, w, DefaultGC(d, s), 50, 50, msg, strlen(msg));
67 /* exit on key press */
68 if (e.type == KeyPress)
69 break;
72 /* close connection to server */
73 XCloseDisplay(d);
75 return 0;
79 EXPORT Display* x_open_display(char* name) {
80 Display* d;
81 d = XOpenDisplay(name);
82 printf("Opening X Display '%s' ==> %p\n", name, (void*)d);
83 return d;
87 EXPORT void x_close_display(Display* d) {
88 XCloseDisplay(d);
92 /*fixme per display*/
93 char* globalSelection = 0;
94 int globalSelectionSize = 0;
96 EXPORT void slate_clipboard_update(Display* d, Window w) {
97 Window selectionOwner;
98 Atom type;
99 int format, result;
100 unsigned long len, bytes_left, size;
101 unsigned char* data;
102 selectionOwner = XGetSelectionOwner (d, XA_PRIMARY);
104 if (selectionOwner == None) return;
105 if (selectionOwner == w) return; /*already on our globalSelection*/
107 XConvertSelection(d, XA_PRIMARY, XA_STRING, None, selectionOwner, CurrentTime);
108 XFlush(d);
109 XGetWindowProperty(d, selectionOwner, XA_STRING, 0, 0, 0, /*don't grab any*/
110 AnyPropertyType, &type, &format, &len, &bytes_left, &data);
111 printf ("type:%i len:%i format:%i byte_left:%i\n", (int)type, (int)len, (int)format, (int)bytes_left);
112 if (bytes_left > 0) {
113 size = bytes_left;
114 result = XGetWindowProperty (d, selectionOwner, XA_STRING, 0, size, 0,
115 AnyPropertyType, &type, &format, &len, &bytes_left, &data);
116 if (result == Success) {
117 free(globalSelection);
118 globalSelection = malloc(size);
119 if (globalSelection == NULL) {
120 globalSelectionSize = 0;
121 XFree(data);
122 return;
124 globalSelectionSize = size;
125 memcpy(globalSelection, data, size);
127 else printf ("FAIL\n");
133 EXPORT int slate_clipboard_size(Display* d, Window w) {
134 return globalSelectionSize;
137 EXPORT void slate_clipboard_copy(Display* d, Window w, char* bytes, int size) {
138 free(globalSelection);
139 globalSelection = malloc(size);
140 if (globalSelection == NULL) {
141 globalSelectionSize = 0;
142 return;
144 globalSelectionSize = size;
145 memcpy(globalSelection, bytes, size);
146 XSetSelectionOwner(d, XA_PRIMARY, w, CurrentTime);
150 EXPORT void slate_clipboard_paste(Display* d, Window w, char* bytes, int size) {
151 if (globalSelection == NULL) return;
152 memcpy(bytes, globalSelection, (size < globalSelectionSize) ? size : globalSelectionSize);
155 EXPORT Window x_create_window(Display* d, int width, int height) {
156 Window w;
157 int s;
158 s = DefaultScreen(d);
160 /* create window */
161 w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, width, height, 1,
162 BlackPixel(d, s), WhitePixel(d, s));
164 /* select kind of events we are interested in */
165 XSelectInput(d, w, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask
166 | ButtonReleaseMask | PointerMotionMask | KeymapStateMask | StructureNotifyMask);
168 /* map (show) the window */
169 XMapWindow(d, w);
171 return w;
175 XEvent globalEvent;
177 EXPORT void x_next_event(Display* d) {
178 /*we should probably fix this and make it per window...
179 also... should we through out extra mouse movements for speed?*/
180 for (;;) {
181 XEvent reply;
183 XNextEvent(d, &globalEvent);
184 if (globalEvent.type != SelectionRequest) break;
186 printf ("prop:%i tar:%i sel:%i\n",
187 (int)globalEvent.xselectionrequest.property,
188 (int)globalEvent.xselectionrequest.target,
189 (int)globalEvent.xselectionrequest.selection);
190 if (globalEvent.xselectionrequest.target == XA_STRING)
192 XChangeProperty (d,
193 globalEvent.xselectionrequest.requestor,
194 globalEvent.xselectionrequest.property,
195 XA_STRING,
197 PropModeReplace,
198 (unsigned char*) globalSelection,
199 globalSelectionSize);
200 reply.xselection.property=globalEvent.xselectionrequest.property;
202 else
204 printf ("No String %i\n",
205 (int)globalEvent.xselectionrequest.target);
206 reply.xselection.property= None;
208 reply.xselection.type= SelectionNotify;
209 reply.xselection.display= globalEvent.xselectionrequest.display;
210 reply.xselection.requestor= globalEvent.xselectionrequest.requestor;
211 reply.xselection.selection=globalEvent.xselectionrequest.selection;
212 reply.xselection.target= globalEvent.xselectionrequest.target;
213 reply.xselection.time = globalEvent.xselectionrequest.time;
214 XSendEvent(d, globalEvent.xselectionrequest.requestor,0,0,&reply);
221 EXPORT int x_event_type() {
223 return globalEvent.type;
227 EXPORT int x_event_keyboard_key(Display* display) {
228 //KeySym XKeycodeToKeysym(Display *display, KeyCode keycode, int index);
229 KeyCode kc;
230 KeySym ks, ksHigh, ksLow;
231 char buf[16];
232 XComposeStatus composeStatus;
234 kc = globalEvent.xkey.keycode;
235 if (0 != XLookupString(&globalEvent.xkey, buf, 1, &ks, &composeStatus)) {
236 return (int)buf[0];
239 ks = XKeycodeToKeysym(display, kc, 0);
240 if (ks > 0xFF00) {
241 return ks & 0xFF;
243 XConvertCase(ks, &ksLow, &ksHigh);
244 if (globalEvent.xkey.state & 3) { /*shift or capslock?*/
245 return ksHigh;
246 } else {
247 return ksLow;
252 EXPORT int x_event_keyboard_modifiers() {
254 return globalEvent.xkey.state;
258 EXPORT int x_event_pointer_x() {
260 return globalEvent.xbutton.x;
264 EXPORT int x_event_pointer_y() {
266 return globalEvent.xbutton.y;
270 EXPORT int x_event_pointer_state() {
272 return globalEvent.xbutton.state;
276 EXPORT int x_event_pointer_button() {
278 return globalEvent.xbutton.button;
282 EXPORT int x_event_resize_width() {
284 return globalEvent.xresizerequest.width;
287 EXPORT int x_event_resize_height() {
289 return globalEvent.xresizerequest.height;
293 EXPORT int x_event_configure_width() {
295 return globalEvent.xconfigure.width;
298 EXPORT int x_event_configure_height() {
300 return globalEvent.xconfigure.height;
304 EXPORT cairo_t * slate_cairo_create_context(cairo_surface_t *surface)
306 return cairo_create(surface);
309 EXPORT void slate_cairo_destroy_context(cairo_t *context)
311 cairo_destroy(context);
315 EXPORT void slate_cairo_paint(cairo_t* c) {
317 cairo_show_page(c);
322 EXPORT void slate_cairo_resize(cairo_surface_t* surface, int width, int height) {
324 cairo_xlib_surface_set_size(surface, width, height);
329 EXPORT cairo_surface_t * slate_cairo_create_surface(Display* d, Window w, int width, int height) {
330 return cairo_xlib_surface_create(d, w, DefaultVisual(d, 0), width, height);
334 EXPORT void slate_cairo_destroy_surface(cairo_surface_t *surface) {
335 cairo_surface_destroy(surface);
340 /******************************************************************************
341 * Context
342 ******************************************************************************/
344 EXPORT void clip(cairo_t *context)
346 cairo_clip(context);
349 EXPORT void clip_preserve(cairo_t *context)
351 cairo_clip_preserve(context);
355 EXPORT void fill(cairo_t *context)
357 cairo_fill(context);
360 EXPORT void fill_preserve(cairo_t *context)
362 cairo_fill_preserve(context);
365 EXPORT void restore(cairo_t *context)
367 cairo_restore(context);
370 EXPORT void save(cairo_t *context)
372 cairo_save(context);
375 EXPORT slate_int_t get_line_width(cairo_t *context)
377 union float_int_union u;
378 u.f = (float)cairo_get_line_width(context);
379 return u.i;
382 EXPORT void set_line_width(cairo_t *context, slate_int_t width)
384 union float_int_union u;
385 u.i = width;
386 cairo_set_line_width(context, u.f);
389 EXPORT void set_source_rgb(cairo_t *context, slate_int_t r, slate_int_t g, slate_int_t b)
391 union float_int_union ru,bu,gu;
392 ru.i = r;
393 bu.i = b;
394 gu.i = g;
396 cairo_set_source_rgb(context, ru.f, gu.f, bu.f);
399 EXPORT void set_source_rgba(cairo_t *context, slate_int_t r, slate_int_t g, slate_int_t b, slate_int_t a)
401 union float_int_union ru,bu,gu,au;
402 ru.i = r;
403 bu.i = b;
404 gu.i = g;
405 au.i = a;
406 cairo_set_source_rgba(context, ru.f, gu.f, bu.f, au.f);
409 EXPORT void stroke(cairo_t *context)
411 cairo_stroke(context);
414 EXPORT void stroke_preserve(cairo_t *context)
416 cairo_stroke_preserve(context);
419 /******************************************************************************
420 * Path
421 ******************************************************************************/
423 EXPORT void close_path(cairo_t *context)
425 cairo_close_path(context);
428 EXPORT void line_to(cairo_t *context, slate_int_t x, slate_int_t y)
430 union float_int_union xu, yu;
431 xu.i = x;
432 yu.i = y;
433 cairo_line_to(context, xu.f, yu.f);
436 EXPORT void move_to(cairo_t *context, slate_int_t x, slate_int_t y)
438 union float_int_union xu, yu;
439 xu.i = x;
440 yu.i = y;
441 cairo_move_to(context, xu.f, yu.f);
444 EXPORT void new_path(cairo_t *context)
446 cairo_new_path(context);
449 EXPORT void rectangle(cairo_t *context, slate_int_t x, slate_int_t y, slate_int_t w, slate_int_t h)
451 union float_int_union xu, yu, wu, hu;
452 xu.i = x;
453 yu.i = y;
454 wu.i = w;
455 hu.i = h;
456 cairo_rectangle(context, xu.f, yu.f, wu.f, hu.f);
459 /******************************************************************************
460 * Transformation
461 ******************************************************************************/
463 EXPORT void translate(cairo_t *context, slate_int_t x, slate_int_t y)
465 union float_int_union xu, yu;
466 xu.i = x;
467 yu.i = y;
468 cairo_translate(context, xu.f, yu.f);
471 EXPORT void scale(cairo_t *context, slate_int_t x, slate_int_t y)
473 union float_int_union xu, yu;
474 xu.i = x;
475 yu.i = y;
476 cairo_scale(context, xu.f, yu.f);
479 /******************************************************************************
480 * Text
481 ******************************************************************************/
483 EXPORT void select_font_face(cairo_t *context, const char *family, slate_int_t italic, slate_int_t bold)
485 cairo_select_font_face(
486 context,
487 family,
488 italic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL,
489 bold ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
492 EXPORT void set_font_size(cairo_t *context, slate_int_t size)
494 union float_int_union su;
495 su.i = size;
496 cairo_set_font_size(context, su.f);
499 EXPORT void show_text(cairo_t *context, const char *text)
501 if(!*text) // Cairo has insufficient checking
502 return;
503 cairo_show_text(context, text);
509 /* TODO list:
511 Context
512 ==========================================================
513 cairo_status_t cairo_status (cairo_t *cr);
514 cairo_surface_t* cairo_get_target (cairo_t *cr);
515 void cairo_set_source (cairo_t *cr,
516 cairo_pattern_t *source);
517 void cairo_set_source_surface (cairo_t *cr,
518 cairo_surface_t *surface,
519 double x,
520 double y);
521 cairo_pattern_t* cairo_get_source (cairo_t *cr);
522 void cairo_set_antialias (cairo_t *cr,
523 cairo_antialias_t antialias);
524 cairo_antialias_t cairo_get_antialias (cairo_t *cr);
525 void cairo_set_dash (cairo_t *cr,
526 double *dashes,
527 int num_dashes,
528 double offset);
529 void cairo_set_fill_rule (cairo_t *cr,
530 cairo_fill_rule_t fill_rule);
531 cairo_fill_rule_t cairo_get_fill_rule (cairo_t *cr);
532 void cairo_set_line_cap (cairo_t *cr,
533 cairo_line_cap_t line_cap);
534 cairo_line_cap_t cairo_get_line_cap (cairo_t *cr);
535 void cairo_set_line_join (cairo_t *cr,
536 cairo_line_join_t line_join);
537 cairo_line_join_t cairo_get_line_join (cairo_t *cr);
538 void cairo_set_miter_limit (cairo_t *cr,
539 double limit);
540 double cairo_get_miter_limit (cairo_t *cr);
541 void cairo_set_operator (cairo_t *cr,
542 cairo_operator_t op);
543 cairo_operator_t cairo_get_operator (cairo_t *cr);
544 void cairo_set_tolerance (cairo_t *cr,
545 double tolerance);
546 double cairo_get_tolerance (cairo_t *cr);
547 void cairo_reset_clip (cairo_t *cr);
548 void cairo_fill_extents (cairo_t *cr,
549 double *x1,
550 double *y1,
551 double *x2,
552 double *y2);
553 cairo_bool_t cairo_in_fill (cairo_t *cr,
554 double x,
555 double y);
556 void cairo_mask (cairo_t *cr,
557 cairo_pattern_t *pattern);
558 void cairo_mask_surface (cairo_t *cr,
559 cairo_surface_t *surface,
560 double surface_x,
561 double surface_y);
562 void cairo_paint (cairo_t *cr);
563 void cairo_paint_with_alpha (cairo_t *cr,
564 double alpha);
565 void cairo_stroke_extents (cairo_t *cr,
566 double *x1,
567 double *y1,
568 double *x2,
569 double *y2);
570 cairo_bool_t cairo_in_stroke (cairo_t *cr,
571 double x,
572 double y);
573 void cairo_copy_page (cairo_t *cr);
574 void cairo_show_page (cairo_t *cr);
576 Path
577 ==========================================================
578 cairo_path_t;
579 union cairo_path_data_t;
580 enum cairo_path_data_type_t;
581 cairo_path_t* cairo_copy_path (cairo_t *cr);
582 cairo_path_t* cairo_copy_path_flat (cairo_t *cr);
583 void cairo_path_destroy (cairo_path_t *path);
584 void cairo_append_path (cairo_t *cr,
585 cairo_path_t *path);
586 void cairo_get_current_point (cairo_t *cr,
587 double *x,
588 double *y);
589 void cairo_new_path (cairo_t *cr);
590 void cairo_close_path (cairo_t *cr);
591 void cairo_arc (cairo_t *cr,
592 double xc,
593 double yc,
594 double radius,
595 double angle1,
596 double angle2);
597 void cairo_arc_negative (cairo_t *cr,
598 double xc,
599 double yc,
600 double radius,
601 double angle1,
602 double angle2);
603 void cairo_curve_to (cairo_t *cr,
604 double x1,
605 double y1,
606 double x2,
607 double y2,
608 double x3,
609 double y3);
610 void cairo_line_to (cairo_t *cr,
611 double x,
612 double y);
613 void cairo_move_to (cairo_t *cr,
614 double x,
615 double y);
616 void cairo_rectangle (cairo_t *cr,
617 double x,
618 double y,
619 double width,
620 double height);
621 void cairo_glyph_path (cairo_t *cr,
622 cairo_glyph_t *glyphs,
623 int num_glyphs);
624 void cairo_text_path (cairo_t *cr,
625 const char *utf8);
626 void cairo_rel_curve_to (cairo_t *cr,
627 double dx1,
628 double dy1,
629 double dx2,
630 double dy2,
631 double dx3,
632 double dy3);
633 void cairo_rel_line_to (cairo_t *cr,
634 double dx,
635 double dy);
636 void cairo_rel_move_to (cairo_t *cr,
637 double dx,
638 double dy);
640 Pattern
641 ==========================================================
642 typedef cairo_pattern_t;
643 void cairo_pattern_add_color_stop_rgb
644 (cairo_pattern_t *pattern,
645 double offset,
646 double red,
647 double green,
648 double blue);
649 void cairo_pattern_add_color_stop_rgba
650 (cairo_pattern_t *pattern,
651 double offset,
652 double red,
653 double green,
654 double blue,
655 double alpha);
656 cairo_pattern_t* cairo_pattern_create_rgb (double red,
657 double green,
658 double blue);
659 cairo_pattern_t* cairo_pattern_create_rgba (double red,
660 double green,
661 double blue,
662 double alpha);
663 cairo_pattern_t* cairo_pattern_create_for_surface
664 (cairo_surface_t *surface);
665 cairo_pattern_t* cairo_pattern_create_linear
666 (double x0,
667 double y0,
668 double x1,
669 double y1);
670 cairo_pattern_t* cairo_pattern_create_radial
671 (double cx0,
672 double cy0,
673 double radius0,
674 double cx1,
675 double cy1,
676 double radius1);
677 void cairo_pattern_destroy (cairo_pattern_t *pattern);
678 cairo_pattern_t* cairo_pattern_reference (cairo_pattern_t *pattern);
679 cairo_status_t cairo_pattern_status (cairo_pattern_t *pattern);
680 enum cairo_extend_t;
681 void cairo_pattern_set_extend (cairo_pattern_t *pattern,
682 cairo_extend_t extend);
683 cairo_extend_t cairo_pattern_get_extend (cairo_pattern_t *pattern);
684 enum cairo_filter_t;
685 void cairo_pattern_set_filter (cairo_pattern_t *pattern,
686 cairo_filter_t filter);
687 cairo_filter_t cairo_pattern_get_filter (cairo_pattern_t *pattern);
688 void cairo_pattern_set_matrix (cairo_pattern_t *pattern,
689 const cairo_matrix_t *matrix);
690 void cairo_pattern_get_matrix (cairo_pattern_t *pattern,
691 cairo_matrix_t *matrix);
693 Transformation
694 ==========================================================
695 void cairo_translate (cairo_t *cr,
696 double tx,
697 double ty);
698 void cairo_rotate (cairo_t *cr,
699 double angle);
700 void cairo_transform (cairo_t *cr,
701 const cairo_matrix_t *matrix);
702 void cairo_set_matrix (cairo_t *cr,
703 const cairo_matrix_t *matrix);
704 void cairo_get_matrix (cairo_t *cr,
705 cairo_matrix_t *matrix);
706 void cairo_identity_matrix (cairo_t *cr);
707 void cairo_user_to_device (cairo_t *cr,
708 double *x,
709 double *y);
710 void cairo_user_to_device_distance (cairo_t *cr,
711 double *dx,
712 double *dy);
713 void cairo_device_to_user (cairo_t *cr,
714 double *x,
715 double *y);
716 void cairo_device_to_user_distance (cairo_t *cr,
717 double *dx,
718 double *dy);
720 Text
721 ==========================================================
722 cairo_glyph_t;
723 enum cairo_font_slant_t;
724 enum cairo_font_weight_t;
725 void cairo_set_font_matrix (cairo_t *cr,
726 const cairo_matrix_t *matrix);
727 void cairo_get_font_matrix (cairo_t *cr,
728 cairo_matrix_t *matrix);
729 void cairo_set_font_options (cairo_t *cr,
730 const cairo_font_options_t *options);
731 void cairo_get_font_options (cairo_t *cr,
732 cairo_font_options_t *options);
733 void cairo_show_glyphs (cairo_t *cr,
734 cairo_glyph_t *glyphs,
735 int num_glyphs);
736 cairo_font_face_t* cairo_get_font_face (cairo_t *cr);
737 void cairo_font_extents (cairo_t *cr,
738 cairo_font_extents_t *extents);
739 void cairo_set_font_face (cairo_t *cr,
740 cairo_font_face_t *font_face);
741 void cairo_text_extents (cairo_t *cr,
742 const char *utf8,
743 cairo_text_extents_t *extents);
744 void cairo_glyph_extents (cairo_t *cr,
745 cairo_glyph_t *glyphs,
746 int num_glyphs,
747 cairo_text_extents_t *extents);
749 ==========================================================