00001 #include "bcbitmap.h"
00002 #include "bcclipboard.h"
00003 #include "bcdisplayinfo.h"
00004 #include "bcmenubar.h"
00005 #include "bcpixmap.h"
00006 #include "bcpopup.h"
00007 #include "bcpopupmenu.h"
00008 #include "bcrepeater.h"
00009 #include "bcresources.h"
00010 #include "bcsignals.h"
00011 #include "bcsubwindow.h"
00012 #include "bcsynchronous.h"
00013 #include "bctimer.h"
00014 #include "bcwidgetgrid.h"
00015 #include "bcwindowbase.h"
00016 #include "bcwindowevents.h"
00017 #include "colormodels.h"
00018 #include "colors.h"
00019 #include "condition.h"
00020 #include "cursors.h"
00021 #include "bchash.h"
00022 #include "fonts.h"
00023 #include "keys.h"
00024 #include "language.h"
00025 #include "mutex.h"
00026 #include "sizes.h"
00027 #include "vframe.h"
00028
00029 #ifdef HAVE_GL
00030 #include <GL/gl.h>
00031 #endif
00032 #include <string.h>
00033 #include <unistd.h>
00034
00035 #include <X11/extensions/Xvlib.h>
00036 #include <X11/extensions/shape.h>
00037
00038
00039 BC_ResizeCall::BC_ResizeCall(int w, int h)
00040 {
00041 this->w = w;
00042 this->h = h;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 BC_Resources BC_WindowBase::resources;
00056
00057 Window XGroupLeader = 0;
00058
00059 BC_WindowBase::BC_WindowBase()
00060 {
00061
00062 BC_WindowBase::initialize();
00063 }
00064
00065 BC_WindowBase::~BC_WindowBase()
00066 {
00067 #ifdef HAVE_LIBXXF86VM
00068 if(window_type == VIDMODE_SCALED_WINDOW && vm_switched)
00069 {
00070 restore_vm();
00071 }
00072 #endif
00073
00074 hide_tooltip();
00075 if(window_type != MAIN_WINDOW)
00076 {
00077 if(top_level->active_menubar == this) top_level->active_menubar = 0;
00078 if(top_level->active_popup_menu == this) top_level->active_popup_menu = 0;
00079 if(top_level->active_subwindow == this) top_level->active_subwindow = 0;
00080
00081 parent_window->subwindows->remove(this);
00082 }
00083
00084
00085
00086 is_deleting = 1;
00087 if(subwindows)
00088 {
00089 while(subwindows->total)
00090 {
00091
00092 delete subwindows->values[0];
00093 }
00094 delete subwindows;
00095 }
00096
00097 if(widgetgrids)
00098 {
00099 while (widgetgrids->total)
00100 {
00101 delete widgetgrids->last();
00102 widgetgrids->remove();
00103 }
00104 delete widgetgrids;
00105 }
00106
00107
00108 delete pixmap;
00109
00110
00111 #ifdef HAVE_GL
00112 if(!gl_win_context || !get_resources()->get_synchronous())
00113 #endif
00114 XDestroyWindow(top_level->display, win);
00115
00116 if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap;
00117 if(icon_pixmap) delete icon_pixmap;
00118 if(temp_bitmap) delete temp_bitmap;
00119
00120
00121
00122
00123
00124 if(window_type == MAIN_WINDOW)
00125 {
00126 XFreeGC(display, gc);
00127 #ifdef HAVE_XFT
00128 if(largefont_xft)
00129 XftFontClose (display, (XftFont*)largefont_xft);
00130 if(mediumfont_xft)
00131 XftFontClose (display, (XftFont*)mediumfont_xft);
00132 if(smallfont_xft)
00133 XftFontClose (display, (XftFont*)smallfont_xft);
00134 #endif
00135 flush();
00136
00137
00138 #ifdef HAVE_GL
00139 if(!gl_win_context || !get_resources()->get_synchronous())
00140 #endif
00141 XCloseDisplay(display);
00142 clipboard->stop_clipboard();
00143 delete clipboard;
00144 }
00145 else
00146 {
00147 flush();
00148 }
00149
00150
00151
00152
00153 #ifdef HAVE_GL
00154 if(gl_win_context && get_resources()->get_synchronous())
00155 {
00156 printf("BC_WindowBase::~BC_WindowBase window deleted but opengl deletion is not\n"
00157 "implemented for BC_Pixmap.\n");
00158 get_resources()->get_synchronous()->delete_window(this);
00159 }
00160 #endif
00161
00162 resize_history.remove_all_objects();
00163 common_events.remove_all_objects();
00164 delete event_lock;
00165 delete event_condition;
00166
00167 UNSET_ALL_LOCKS(this)
00168 }
00169
00170 int BC_WindowBase::initialize()
00171 {
00172 test_keypress = 0;
00173 is_deleting = 0;
00174 window_lock = 0;
00175 x = 0;
00176 y = 0;
00177 w = 0;
00178 h = 0;
00179 bg_color = -1;
00180 top_level = 0;
00181 parent_window = 0;
00182 subwindows = 0;
00183 widgetgrids = 0;
00184 xvideo_port_id = -1;
00185 video_on = 0;
00186 motion_events = 0;
00187 resize_events = 0;
00188 translation_events = 0;
00189 ctrl_mask = shift_mask = alt_mask = 0;
00190 cursor_x = cursor_y = button_number = 0;
00191 button_down = 0;
00192 button_pressed = 0;
00193 button_time1 = button_time2 = 0;
00194 double_click = 0;
00195 last_motion_win = 0;
00196 key_pressed = 0;
00197 active_menubar = 0;
00198 active_popup_menu = 0;
00199 active_subwindow = 0;
00200 pixmap = 0;
00201 bg_pixmap = 0;
00202 tooltip_text[0] = 0;
00203 persistant_tooltip = 0;
00204
00205 tooltip_popup = 0;
00206 tooltip_done = 0;
00207 current_font = MEDIUMFONT;
00208 current_color = BLACK;
00209 current_cursor = ARROW_CURSOR;
00210 hourglass_total = 0;
00211 is_dragging = 0;
00212 shared_bg_pixmap = 0;
00213 icon_pixmap = 0;
00214 window_type = MAIN_WINDOW;
00215 translation_count = 0;
00216 x_correction = y_correction = 0;
00217 temp_bitmap = 0;
00218 tooltip_on = 0;
00219 temp_cursor = 0;
00220 toggle_value = 0;
00221 toggle_drag = 0;
00222 has_focus = 0;
00223 is_hourglass = 0;
00224 is_transparent = 0;
00225 #ifdef HAVE_LIBXXF86VM
00226 vm_switched = 0;
00227 #endif
00228 largefont_xft = 0;
00229 mediumfont_xft = 0;
00230 smallfont_xft = 0;
00231
00232 event_lock = new Mutex("BC_WindowBase::event_lock");
00233 event_condition = new Condition(0, "BC_WindowBase::event_condition");
00234 cursor_timer = new Timer;
00235 event_thread = 0;
00236 #ifdef HAVE_GL
00237 gl_win_context = 0;
00238 #endif
00239
00240 return 0;
00241 }
00242
00243 #define DEFAULT_EVENT_MASKS EnterWindowMask | \
00244 LeaveWindowMask | \
00245 ButtonPressMask | \
00246 ButtonReleaseMask | \
00247 PointerMotionMask | \
00248 FocusChangeMask
00249
00250
00251 int BC_WindowBase::create_window(BC_WindowBase *parent_window,
00252 char *title,
00253 int x,
00254 int y,
00255 int w,
00256 int h,
00257 int minw,
00258 int minh,
00259 int allow_resize,
00260 int private_color,
00261 int hide,
00262 int bg_color,
00263 char *display_name,
00264 int window_type,
00265 BC_Pixmap *bg_pixmap,
00266 int group_it)
00267 {
00268 XSetWindowAttributes attr;
00269 unsigned long mask;
00270 XSizeHints size_hints;
00271 int root_w;
00272 int root_h;
00273 #ifdef HAVE_LIBXXF86VM
00274 int vm;
00275 #endif
00276
00277 id = get_resources()->get_id();
00278
00279
00280 get_resources()->create_window_lock->lock("BC_WindowBase::create_window");
00281
00282 if(parent_window) top_level = parent_window->top_level;
00283
00284 #ifdef HAVE_LIBXXF86VM
00285 if(window_type == VIDMODE_SCALED_WINDOW)
00286 closest_vm(&vm,&w,&h);
00287 #endif
00288
00289 this->x = x;
00290 this->y = y;
00291 this->w = w;
00292 this->h = h;
00293 this->bg_color = bg_color;
00294 this->window_type = window_type;
00295 this->hidden = hide;
00296 this->private_color = private_color;
00297 this->parent_window = parent_window;
00298 this->bg_pixmap = bg_pixmap;
00299 this->allow_resize = allow_resize;
00300 strcpy(this->title, _(title));
00301 if(bg_pixmap) shared_bg_pixmap = 1;
00302
00303 if(parent_window) top_level = parent_window->top_level;
00304
00305 subwindows = new BC_SubWindowList;
00306 widgetgrids = new BC_WidgetGridList;
00307
00308
00309 if(window_type == MAIN_WINDOW)
00310 {
00311 top_level = this;
00312 parent_window = this;
00313
00314
00315
00316 XInitThreads();
00317
00318
00319
00320 display = init_display(display_name);
00321
00322
00323
00324 root_w = get_root_w(1, 0);
00325 root_h = get_root_h(0);
00326 if(this->x + this->w > root_w) this->x = root_w - this->w;
00327 if(this->y + this->h > root_h) this->y = root_h - this->h;
00328 if(this->x < 0) this->x = 0;
00329 if(this->y < 0) this->y = 0;
00330 screen = DefaultScreen(display);
00331 rootwin = RootWindow(display, screen);
00332
00333
00334 vis = DefaultVisual(display, screen);
00335 default_depth = DefaultDepth(display, screen);
00336
00337 client_byte_order = (*(u_int32_t*)"a ") & 0x00000001;
00338 server_byte_order = (XImageByteOrder(display) == MSBFirst) ? 0 : 1;
00339
00340
00341
00342 init_colors();
00343
00344 if(resources.use_shm < 0) resources.initialize_display(this);
00345 x_correction = get_resources()->get_left_border();
00346 y_correction = get_resources()->get_top_border();
00347
00348 if(this->bg_color == -1)
00349 this->bg_color = resources.get_bg_color();
00350
00351
00352
00353
00354 init_fonts();
00355 init_gc();
00356 init_cursors();
00357
00358
00359 mask = CWEventMask |
00360 CWBackPixel |
00361 CWColormap |
00362 CWCursor;
00363
00364 attr.event_mask = DEFAULT_EVENT_MASKS |
00365 StructureNotifyMask |
00366 KeyPressMask;
00367
00368 attr.background_pixel = get_color(this->bg_color);
00369 attr.colormap = cmap;
00370 attr.cursor = get_cursor_struct(ARROW_CURSOR);
00371
00372 win = XCreateWindow(display,
00373 rootwin,
00374 this->x,
00375 this->y,
00376 this->w,
00377 this->h,
00378 0,
00379 top_level->default_depth,
00380 InputOutput,
00381 vis,
00382 mask,
00383 &attr);
00384
00385 XGetNormalHints(display, win, &size_hints);
00386
00387 size_hints.flags = PSize | PMinSize | PMaxSize;
00388 size_hints.width = this->w;
00389 size_hints.height = this->h;
00390 size_hints.min_width = allow_resize ? minw : this->w;
00391 size_hints.max_width = allow_resize ? 32767 : this->w;
00392 size_hints.min_height = allow_resize ? minh : this->h;
00393 size_hints.max_height = allow_resize ? 32767 : this->h;
00394 if(x > -BC_INFINITY && x < BC_INFINITY)
00395 {
00396 size_hints.flags |= PPosition;
00397 size_hints.x = this->x;
00398 size_hints.y = this->y;
00399 }
00400
00401 XSetStandardProperties(display,
00402 win,
00403 title,
00404 title,
00405 None,
00406 0,
00407 0,
00408 &size_hints);
00409 get_atoms();
00410
00411 clipboard = new BC_Clipboard(display_name);
00412 clipboard->start_clipboard();
00413
00414 if (group_it)
00415 {
00416 Atom ClientLeaderXAtom;
00417 if (XGroupLeader == 0)
00418 XGroupLeader = win;
00419 char *instance_name = "cinelerra";
00420 char *class_name = "Cinelerra";
00421 XClassHint *class_hints = XAllocClassHint();
00422 class_hints->res_name = instance_name;
00423 class_hints->res_class = class_name;
00424 XSetClassHint(top_level->display, win, class_hints);
00425 XFree(class_hints);
00426 ClientLeaderXAtom = XInternAtom(display, "WM_CLIENT_LEADER", True);
00427 XChangeProperty(display,
00428 win,
00429 ClientLeaderXAtom,
00430 XA_WINDOW,
00431 32,
00432 PropModeReplace,
00433 (unsigned char *)&XGroupLeader,
00434 true);
00435
00436 }
00437
00438 }
00439
00440 #ifdef HAVE_LIBXXF86VM
00441 if(window_type == VIDMODE_SCALED_WINDOW && vm != -1)
00442 {
00443 scale_vm (vm);
00444 vm_switched = 1;
00445 }
00446 #endif
00447
00448 #ifdef HAVE_LIBXXF86VM
00449 if(window_type == POPUP_WINDOW || window_type == VIDMODE_SCALED_WINDOW)
00450 #else
00451 if(window_type == POPUP_WINDOW)
00452 #endif
00453 {
00454 mask = CWEventMask |
00455 CWBackPixel |
00456 CWColormap |
00457 CWOverrideRedirect |
00458 CWSaveUnder |
00459 CWCursor;
00460
00461 attr.event_mask = DEFAULT_EVENT_MASKS |
00462 KeyPressMask;
00463
00464 if(this->bg_color == -1)
00465 this->bg_color = resources.get_bg_color();
00466 attr.background_pixel = top_level->get_color(bg_color);
00467 attr.colormap = top_level->cmap;
00468 if(top_level->is_hourglass)
00469 attr.cursor = top_level->get_cursor_struct(HOURGLASS_CURSOR);
00470 else
00471 attr.cursor = top_level->get_cursor_struct(ARROW_CURSOR);
00472 attr.override_redirect = True;
00473 attr.save_under = True;
00474
00475 win = XCreateWindow(top_level->display,
00476 top_level->rootwin,
00477 this->x,
00478 this->y,
00479 this->w,
00480 this->h,
00481 0,
00482 top_level->default_depth,
00483 InputOutput,
00484 top_level->vis,
00485 mask,
00486 &attr);
00487 }
00488
00489 if(window_type == SUB_WINDOW)
00490 {
00491 mask = CWBackPixel |
00492 CWEventMask |
00493 CWCursor;
00494 attr.event_mask = DEFAULT_EVENT_MASKS;
00495 attr.background_pixel = top_level->get_color(this->bg_color);
00496 if(top_level->is_hourglass)
00497 attr.cursor = top_level->get_cursor_struct(HOURGLASS_CURSOR);
00498 else
00499 attr.cursor = top_level->get_cursor_struct(ARROW_CURSOR);
00500 win = XCreateWindow(top_level->display,
00501 parent_window->win,
00502 this->x,
00503 this->y,
00504 this->w,
00505 this->h,
00506 0,
00507 top_level->default_depth,
00508 InputOutput,
00509 top_level->vis,
00510 mask,
00511 &attr);
00512 init_window_shape();
00513 XMapWindow(top_level->display, win);
00514 }
00515
00516
00517 pixmap = new BC_Pixmap(this, this->w, this->h);
00518
00519
00520
00521 if(window_type == MAIN_WINDOW)
00522 {
00523 if(get_resources()->bg_image && !bg_pixmap && bg_color < 0)
00524 {
00525 this->bg_pixmap = new BC_Pixmap(this,
00526 get_resources()->bg_image,
00527 PIXMAP_OPAQUE);
00528 }
00529
00530 if(!hidden) show_window();
00531
00532 }
00533
00534
00535
00536
00537 draw_background(0, 0, this->w, this->h);
00538 flash();
00539
00540
00541 #ifdef HAVE_LIBXXF86VM
00542 if(window_type == POPUP_WINDOW || window_type == VIDMODE_SCALED_WINDOW)
00543 #else
00544 if(window_type == POPUP_WINDOW)
00545 #endif
00546 {
00547 init_window_shape();
00548 if(!hidden) show_window();
00549 }
00550 get_resources()->create_window_lock->unlock();
00551
00552 return 0;
00553 }
00554
00555 Display* BC_WindowBase::init_display(char *display_name)
00556 {
00557 Display* display;
00558
00559 if(display_name && display_name[0] == 0) display_name = NULL;
00560 if((display = XOpenDisplay(display_name)) == NULL)
00561 {
00562 printf("BC_WindowBase::init_display: cannot connect to X server %s\n",
00563 display_name);
00564 if(getenv("DISPLAY") == NULL)
00565 {
00566 printf("'DISPLAY' environment variable not set.\n");
00567 exit(1);
00568 }
00569 else
00570
00571 {
00572 if((display = XOpenDisplay(0)) == NULL)
00573 {
00574 printf("BC_WindowBase::init_display: cannot connect to default X server.\n");
00575 exit(1);
00576 }
00577 }
00578 }
00579 return display;
00580 }
00581
00582 Display* BC_WindowBase::get_display()
00583 {
00584 return top_level->display;
00585 }
00586
00587 int BC_WindowBase::get_screen()
00588 {
00589 return top_level->screen;
00590 }
00591
00592 int BC_WindowBase::run_window()
00593 {
00594 done = 0;
00595 return_value = 0;
00596
00597
00598
00599
00600
00601 if(window_type == MAIN_WINDOW)
00602 {
00603
00604 set_repeat(get_resources()->tooltip_delay);
00605 }
00606
00607
00608 event_thread = new BC_WindowEvents(this);
00609 event_thread->start();
00610
00611
00612 while(!done)
00613 {
00614 dispatch_event();
00615 }
00616
00617 unset_all_repeaters();
00618 hide_tooltip();
00619 delete event_thread;
00620 event_thread = 0;
00621 event_condition->reset();
00622 common_events.remove_all_objects();
00623 done = 0;
00624
00625 return return_value;
00626 }
00627
00628 int BC_WindowBase::get_key_masks(XEvent *event)
00629 {
00630
00631
00632
00633 ctrl_mask = (event->xkey.state & ControlMask) ? 1 : 0;
00634
00635 shift_mask = (event->xkey.state & ShiftMask) ? 1 : 0;
00636 alt_mask = (event->xkey.state & Mod1Mask) ? 1 : 0;
00637 return 0;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646 int BC_WindowBase::dispatch_event()
00647 {
00648 XEvent *event = 0;
00649 Window tempwin;
00650 KeySym keysym;
00651 char keys_return[2];
00652 int result;
00653 XClientMessageEvent *ptr;
00654 int temp;
00655 int cancel_resize, cancel_translation;
00656
00657 key_pressed = 0;
00658
00659
00660
00661 if(get_event_count() ||
00662 (!motion_events && !resize_events && !translation_events))
00663 {
00664
00665 event = get_event();
00666
00667 lock_window("BC_WindowBase::dispatch_event 1");
00668
00669 }
00670 else
00671
00672 {
00673 lock_window("BC_WindowBase::dispatch_event 2");
00674 if(resize_events)
00675 dispatch_resize_event(last_resize_w, last_resize_h);
00676 else
00677 if(motion_events)
00678 dispatch_motion_event();
00679 else
00680 if(translation_events)
00681 dispatch_translation_event();
00682
00683 unlock_window();
00684 return 0;
00685 }
00686
00687
00688 switch(event->type)
00689 {
00690 case ClientMessage:
00691
00692 if(resize_events) dispatch_resize_event(last_resize_w, last_resize_h);
00693
00694 if(motion_events)
00695 {
00696 dispatch_motion_event();
00697 }
00698
00699 ptr = (XClientMessageEvent*)event;
00700
00701
00702 if(ptr->message_type == ProtoXAtom &&
00703 ptr->data.l[0] == DelWinXAtom)
00704 {
00705 close_event();
00706 }
00707 else
00708 if(ptr->message_type == RepeaterXAtom)
00709 {
00710 dispatch_repeat_event(ptr->data.l[0]);
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 }
00721 else
00722 if(ptr->message_type == SetDoneXAtom)
00723 {
00724 done = 1;
00725 } else
00726 {
00727 recieve_custom_xatoms((xatom_event *)ptr);
00728 }
00729 break;
00730
00731 case FocusIn:
00732 has_focus = 1;
00733 dispatch_focus_in();
00734 break;
00735
00736 case FocusOut:
00737 has_focus = 0;
00738 dispatch_focus_out();
00739 break;
00740
00741
00742 case MapNotify:
00743 break;
00744
00745
00746 case UnmapNotify:
00747 break;
00748
00749 case ButtonPress:
00750 get_key_masks(event);
00751 cursor_x = event->xbutton.x;
00752 cursor_y = event->xbutton.y;
00753 button_number = event->xbutton.button;
00754 event_win = event->xany.window;
00755 if (button_number != 4 && button_number != 5)
00756 button_down = 1;
00757 button_pressed = event->xbutton.button;
00758 button_time1 = button_time2;
00759 button_time2 = event->xbutton.time;
00760 drag_x = cursor_x;
00761 drag_y = cursor_y;
00762 drag_win = event_win;
00763 drag_x1 = cursor_x - get_resources()->drag_radius;
00764 drag_x2 = cursor_x + get_resources()->drag_radius;
00765 drag_y1 = cursor_y - get_resources()->drag_radius;
00766 drag_y2 = cursor_y + get_resources()->drag_radius;
00767
00768 if(button_time2 - button_time1 < resources.double_click)
00769 {
00770
00771 double_click = 1;
00772 button_time2 = button_time1 = 0;
00773 }
00774 else
00775 double_click = 0;
00776
00777 dispatch_button_press();
00778 break;
00779
00780 case ButtonRelease:
00781 get_key_masks(event);
00782 button_number = event->xbutton.button;
00783 event_win = event->xany.window;
00784 if (button_number != 4 && button_number != 5)
00785 button_down = 0;
00786
00787 dispatch_button_release();
00788
00789 break;
00790
00791 case Expose:
00792 event_win = event->xany.window;
00793 dispatch_expose_event();
00794 break;
00795
00796 case MotionNotify:
00797 get_key_masks(event);
00798
00799 if(motion_events && last_motion_win != event->xany.window)
00800 {
00801 dispatch_motion_event();
00802 }
00803
00804
00805 motion_events = 1;
00806 last_motion_x = event->xmotion.x;
00807 last_motion_y = event->xmotion.y;
00808 last_motion_win = event->xany.window;
00809 break;
00810
00811 case ConfigureNotify:
00812 get_key_masks(event);
00813 XTranslateCoordinates(top_level->display,
00814 top_level->win,
00815 top_level->rootwin,
00816 0,
00817 0,
00818 &last_translate_x,
00819 &last_translate_y,
00820 &tempwin);
00821 last_resize_w = event->xconfigure.width;
00822 last_resize_h = event->xconfigure.height;
00823
00824 cancel_resize = 0;
00825 cancel_translation = 0;
00826
00827
00828 for(int i = 0; i < resize_history.total && !cancel_resize; i++)
00829 {
00830 if(resize_history.values[i]->w == last_resize_w &&
00831 resize_history.values[i]->h == last_resize_h)
00832 {
00833 delete resize_history.values[i];
00834 resize_history.remove_number(i);
00835 cancel_resize = 1;
00836 }
00837 }
00838
00839 if(last_resize_w == w && last_resize_h == h)
00840 cancel_resize = 1;
00841
00842 if(!cancel_resize)
00843 {
00844 resize_events = 1;
00845 }
00846
00847 if((last_translate_x == x && last_translate_y == y))
00848 cancel_translation = 1;
00849
00850 if(!cancel_translation)
00851 {
00852 translation_events = 1;
00853 }
00854
00855 translation_count++;
00856 break;
00857
00858 case KeyPress:
00859 get_key_masks(event);
00860 keys_return[0] = 0;
00861 XLookupString((XKeyEvent*)event, keys_return, 1, &keysym, 0);
00862
00863
00864
00865
00866 if(keysym > 0xffe0 && keysym < 0xffff) break;
00867
00868
00869 if(test_keypress) printf("BC_WindowBase::dispatch_event %x\n", keysym);
00870
00871
00872 switch(keysym)
00873 {
00874
00875 case XK_Alt_L:
00876 case XK_Alt_R:
00877 case XK_Shift_L:
00878 case XK_Shift_R:
00879 case XK_Control_L:
00880 case XK_Control_R:
00881 key_pressed = 0;
00882 break;
00883
00884
00885 case XK_Return: key_pressed = RETURN; break;
00886 case XK_Up: key_pressed = UP; break;
00887 case XK_Down: key_pressed = DOWN; break;
00888 case XK_Left: key_pressed = LEFT; break;
00889 case XK_Right: key_pressed = RIGHT; break;
00890 case XK_Next: key_pressed = PGDN; break;
00891 case XK_Prior: key_pressed = PGUP; break;
00892 case XK_BackSpace: key_pressed = BACKSPACE; break;
00893 case XK_Escape: key_pressed = ESC; break;
00894 case XK_Tab:
00895 if(shift_down())
00896 key_pressed = LEFTTAB;
00897 else
00898 key_pressed = TAB;
00899 break;
00900 case XK_ISO_Left_Tab: key_pressed = LEFTTAB; break;
00901 case XK_underscore: key_pressed = '_'; break;
00902 case XK_asciitilde: key_pressed = '~'; break;
00903 case XK_Delete: key_pressed = DELETE; break;
00904 case XK_Home: key_pressed = HOME; break;
00905 case XK_End: key_pressed = END; break;
00906
00907
00908 case XK_KP_Enter: key_pressed = KPENTER; break;
00909 case XK_KP_Add: key_pressed = KPPLUS; break;
00910 case XK_KP_1:
00911 case XK_KP_End: key_pressed = KP1; break;
00912 case XK_KP_2:
00913 case XK_KP_Down: key_pressed = KP2; break;
00914 case XK_KP_3:
00915 case XK_KP_Page_Down: key_pressed = KP3; break;
00916 case XK_KP_4:
00917 case XK_KP_Left: key_pressed = KP4; break;
00918 case XK_KP_5:
00919 case XK_KP_Begin: key_pressed = KP5; break;
00920 case XK_KP_6:
00921 case XK_KP_Right: key_pressed = KP6; break;
00922 case XK_KP_0:
00923 case XK_KP_Insert: key_pressed = KPINS; break;
00924 case XK_KP_Decimal:
00925 case XK_KP_Delete: key_pressed = KPDEL; break;
00926 default:
00927
00928 key_pressed = keysym & 0xff;
00929 break;
00930 }
00931
00932
00933 result = dispatch_keypress_event();
00934
00935 if(!result)
00936 {
00937 if(key_pressed == 'w' ||
00938 key_pressed == 'W')
00939 {
00940 close_event();
00941 }
00942 }
00943 break;
00944
00945 case LeaveNotify:
00946 event_win = event->xany.window;
00947 dispatch_cursor_leave();
00948 break;
00949
00950 case EnterNotify:
00951 event_win = event->xany.window;
00952 cursor_x = event->xcrossing.x;
00953 cursor_y = event->xcrossing.y;
00954 dispatch_cursor_enter();
00955 break;
00956 }
00957
00958
00959 unlock_window();
00960 if(event) delete event;
00961 return 0;
00962 }
00963
00964 int BC_WindowBase::dispatch_expose_event()
00965 {
00966 int result = 0;
00967 for(int i = 0; i < subwindows->total && !result; i++)
00968 {
00969 result = subwindows->values[i]->dispatch_expose_event();
00970 }
00971
00972
00973 if(!result) expose_event();
00974 return result;
00975 }
00976
00977 int BC_WindowBase::dispatch_resize_event(int w, int h)
00978 {
00979
00980
00981
00982 if(window_type == MAIN_WINDOW)
00983 {
00984 resize_events = 0;
00985 delete pixmap;
00986 pixmap = new BC_Pixmap(this, w, h);
00987
00988 clear_box(0, 0, w, h);
00989 }
00990
00991
00992 for(int i = 0; i < subwindows->total; i++)
00993 {
00994 subwindows->values[i]->dispatch_resize_event(w, h);
00995 }
00996
00997
00998 resize_event(w, h);
00999
01000 if(window_type == MAIN_WINDOW)
01001 {
01002 this->w = w;
01003 this->h = h;
01004