93 * This member variable is set <code>true</code> if the <code>Nokia-UI-Enhancement</code> |
93 * This member variable is set <code>true</code> if the <code>Nokia-UI-Enhancement</code> |
94 * attribute is "CanvasHasBackground". The attribute may be placed in the JAD or the manifest. |
94 * attribute is "CanvasHasBackground". The attribute may be placed in the JAD or the manifest. |
95 */ |
95 */ |
96 private boolean iHasBackgroundImage; |
96 private boolean iHasBackgroundImage; |
97 private boolean iIsGameCanvas; |
97 private boolean iIsGameCanvas; |
|
98 private Object iPaintLock; |
98 |
99 |
99 protected Canvas() |
100 protected Canvas() |
100 { |
101 { |
101 super(); |
102 super(); |
102 synchronized (iToolkit) |
103 synchronized (iToolkit) |
353 { |
355 { |
354 } |
356 } |
355 |
357 |
356 protected abstract void paint(Graphics aGraphics); |
358 protected abstract void paint(Graphics aGraphics); |
357 |
359 |
358 private void handlePaint(int aX, int aY, int aWidth, int aHeight) |
360 private void handlePaint(int aX, int aY, int aWidth, int aHeight, boolean forced) |
359 { |
361 { |
360 synchronized (iToolkit) |
362 synchronized (iToolkit) |
361 { |
363 { |
362 // Track java generated PAINT events so we do not flood the |
364 // Track java generated PAINT events so we do not flood the |
363 // event queue. We need to distinguish between PAINT events |
365 // event queue. We need to distinguish between PAINT events |
384 // |
386 // |
385 iRepaintPending = false; |
387 iRepaintPending = false; |
386 } |
388 } |
387 } |
389 } |
388 |
390 |
389 paint(); |
391 paint(forced); |
390 } |
392 } |
391 |
393 |
392 private void paint() |
394 private void paint(boolean forced) |
393 { |
395 { |
394 Graphics graphics; |
396 Graphics graphics; |
395 int x; |
397 int x; |
396 int y; |
398 int y; |
397 int w; |
399 int w; |
398 int h; |
400 int h; |
399 |
401 |
400 synchronized (iCallbackLock) |
402 synchronized (iPaintLock) |
401 { |
403 { |
402 final int width; |
404 synchronized (iCallbackLock) |
403 final int height; |
405 { |
404 |
406 final int width; |
405 // |
407 final int height; |
406 // Synchronize to protect the update region from concurrent |
408 |
407 // repaint()'s. Note that this is *not* sufficient to ensure |
409 // |
408 // that no other callbacks are called by the event thread |
410 // Synchronize to protect the update region from concurrent |
409 // whilst the current thread is in the repaint routine, for |
411 // repaint()'s. Note that this is *not* sufficient to ensure |
410 // that we use the callbacklock below. |
412 // that no other callbacks are called by the event thread |
411 // |
413 // whilst the current thread is in the repaint routine, for |
412 synchronized (iToolkit) |
414 // that we use the callbacklock below. |
413 { |
415 // |
414 width = iWidth; |
416 synchronized (iToolkit) |
415 height = iHeight; |
417 { |
416 |
418 width = iWidth; |
417 x = iRepaintX1; |
419 height = iHeight; |
418 y = iRepaintY1; |
420 |
419 w = iRepaintX2-iRepaintX1; |
421 x = iRepaintX1; |
420 h = iRepaintY2-iRepaintY1; |
422 y = iRepaintY1; |
421 |
423 w = iRepaintX2-iRepaintX1; |
422 iRepaintX1 = 0; |
424 h = iRepaintY2-iRepaintY1; |
423 iRepaintY1 = 0; |
425 |
424 iRepaintX2 = 0; |
426 iRepaintX1 = 0; |
425 iRepaintY2 = 0; |
427 iRepaintY1 = 0; |
426 |
428 iRepaintX2 = 0; |
427 if (!((w>0) && (h>0) && IsShown())) |
429 iRepaintY2 = 0; |
428 { |
430 |
429 return; |
431 if (!((w>0) && (h>0) && (IsShown() || forced))) |
430 } |
432 { |
431 |
433 return; |
432 graphics = GetPaintGraphics(); |
434 } |
433 } |
435 |
434 |
436 graphics = GetPaintGraphics(); |
435 graphics.reset(width, height); |
437 } |
436 graphics.setClip(x, y, w, h); |
438 |
437 |
439 graphics.reset(width, height); |
438 // On a non-full-screen (normal) mode Canvas the background |
440 graphics.setClip(x, y, w, h); |
439 // image must be initially shown, if the value of the iHasBackgroundImage |
441 |
440 // is true. |
442 // On a non-full-screen (normal) mode Canvas the background |
441 if (!iFullScreen && iHasBackgroundImage && !iIsGameCanvas) |
443 // image must be initially shown, if the value of the iHasBackgroundImage |
442 { |
444 // is true. |
443 drawBackground(true); |
445 if (!iFullScreen && iHasBackgroundImage && !iIsGameCanvas) |
444 } |
446 { |
445 paint(graphics); |
447 drawBackground(true); |
446 } |
448 } |
447 |
449 paint(graphics); |
448 flush(x, y, w, h); |
450 } |
|
451 |
|
452 flush(x, y, w, h); |
|
453 } |
449 } |
454 } |
450 |
455 |
451 void flush(int aX, int aY, int aWidth, int aHeight) |
456 void flush(int aX, int aY, int aWidth, int aHeight) |
452 { |
457 { |
453 final Graphics screenGraphics; |
458 final Graphics screenGraphics; |
567 { |
572 { |
568 final boolean shown = isShown(); |
573 final boolean shown = isShown(); |
569 switch (aEvent) |
574 switch (aEvent) |
570 { |
575 { |
571 case Toolkit.EVENT_PAINT: |
576 case Toolkit.EVENT_PAINT: |
|
577 case Toolkit.EVENT_FORCED_PAINT: |
572 { |
578 { |
573 final int x = aData0 >>> 16; |
579 final int x = aData0 >>> 16; |
574 final int y = aData0 & 0xffff; |
580 final int y = aData0 & 0xffff; |
575 final int w = aData1 >>> 16; |
581 final int w = aData1 >>> 16; |
576 final int h = aData1 & 0xffff; |
582 final int h = aData1 & 0xffff; |
577 handlePaint(x, y, w, h); |
583 boolean forced = (aEvent == Toolkit.EVENT_FORCED_PAINT); |
|
584 handlePaint(x, y, w, h, forced); |
578 } |
585 } |
579 break; |
586 break; |
580 |
587 |
581 case Toolkit.EVENT_KEY_PRESSED: |
588 case Toolkit.EVENT_KEY_PRESSED: |
582 if (shown || isMediaKey(aData0)) |
589 if (shown || isMediaKey(aData0)) |